2012-12-18 44 views
55

不知何故,通過Angular的魔力,如果您使用ng-model併爲其提供布爾值,那麼將檢查您的複選框,如果所述布爾值爲true,並且如果爲false,則選中未選中。AngularJS:反向複選框狀態

<input type="checkbox" ng-model="video.hidden"> 

雖然僅憑這一點是相當令人費解,實際上,我試圖扭轉的選中狀態,因爲與待辦事項例子todo.done意味着盒子被選中,我的模式更像是todo.incomplete

不幸的是我第一次的猜測沒有工作:

<input type="checkbox" ng-model="!video.hidden"> 

我在該模型已經向我口述的位置,所以我不能改變它,不希望有在客戶端進行按摩(因爲我將客戶端對象發送回服務器,因爲它在可信賴的環境中運行)。

更新

這個工作在1.3和不給你字符串(1.2.xxx給你的字符串,而不是布爾值):

<input type="checkbox" ng-model="video.hidden" ng-true-value="false" ng-false-value="true"> 
+0

或者只是使用你用來描述你的模型無論詞的否定:video.shown:?或者在您的控制器中使用一個函數來設置複選框被選中時另一個模型的值......在我看來,這不是一個真正的問題。 – mpm

+0

@camus我說的最後一件事是我不想改變模型,我不應該這樣做。當然,這不是一個真正的問題,但是當一個框架鼓吹易用性時,沒有理由爲什麼我的第一個猜測不應該工作。 – Langdon

+1

使用函數不會改變模型,但會向控制器添加一個函數。沒有框架是一顆銀彈。但是這個很容易擴展,這就是你必須要做的,寫指令。 – mpm

回答

69

你可以說,現在沒有必要自定義指令,棱角分明的支持ng-true-valueng-false-value

https://docs.angularjs.org/api/ng/input/input[checkbox]

你的榜樣應該現在的工作 <input type="checkbox" ng-model="video.hidden" ng-true-value="false" ng-false-value="true">

+1

該解決方案的問題是該複選框在顯示時仍會顯示video.hidden值。 –

+0

看起來像他們在1.3中修復它。 – Langdon

+0

我看到'ng-true-value'和'ng-false-value',但'false'值沒有發送到服務器。也許它被視爲不成功的表單控制。 –

23

我不認爲有辦法純粹在模板中完成此操作。最明顯的方法是創建一個新的作用域變量,該變量手動雙重綁定到您的模型值。因此,像:

<input type="checkbox" ng-model="videoShowing"> 

而在你的控制器:

$scope.videoShowing = !$scope.video.hidden; 

$scope.$watch('video.hidden', function(value) { 
    $scope.videoShowing = !value; 
}); 
$scope.$watch('videoShowing', function(value) { 
    $scope.video.hidden = !value; 
} 

你幾乎可以只使用單向與NG-變化結合,但是這完全不是那麼回事:

<input type="checkbox" ng-checked="!video.hidden" ng-change="???"> 

由於ng-change不會將當前值混合到本地作用域中。如果你處於可以訪問NgModelController的環境中,你可以做些什麼,但是你需要一個自定義指令。製作修改NgModel的格式器和分析器的「反轉」屬性指令並不難。我建議,如果你需要大量的倒置複選框。

編輯

對於後人,使得「倒」屬性是超級簡單,可能也僅僅做到這一點。制定指令起初似乎是一種痛苦,但它確實是角度的方式。

someModule.directive('inverted', function() { 
    return { 
    require: 'ngModel', 
    link: function(scope, element, attrs, ngModel) { 
     ngModel.$parsers.push(function(val) { return !val; }); 
     ngModel.$formatters.push(function(val) { return !val; }); 
    } 
    }; 
}); 

可能需要設置優先級也一樣,還是「不印字」,而不是推動,以確保這些傢伙後運行內置inputDirective的。

+0

這是什麼'ngModel'參數?有沒有關於它的任何文檔?或者它是某種類型的DI魔術? –

+1

「link」的第四個參數反映了你所需要的任何東西。 – jpsimons

13

這似乎是工作

<input type="checkbox" 
     ng-init = "video.checked = !video.hidden" 
     ng-model ="video.checked" 
     ng-change ="video.hidden = !video.checked"/> 

它引入了一個video.checked屬性,是的video.hidden相反,一旦該複選框改變的值更新。

這裏舉例:http://plnkr.co/edit/7HYht6ubkUUJQ0r3g16m?p=preview

+0

不錯,這似乎工作。 ng-init部分是必要的嗎?在'ng-change'內部,你是否無法訪問'input'從中讀取選中的狀態? – Langdon

+0

沒有'ng-init'時,編譯視圖時'video.checked'的值將是'未定義的',即使當'video.hidden'設置爲'false'時,checkbox也會被取消選中。如果你刪除'ng-init',你需要修改控制器中的'videos'對象並從那裏進行初始化。 – jaime

+1

因此,您無法訪問ng-change中的目標'input'?就像,我不能說:'ng-change =「video.hidden =!$ element.checked」' – Langdon

4

我的解決方案使用的指令「否定」,您剛纔添加到「輸入」。 很簡單,不需要更換控制器。

angular 
    .module("<< your module >>") 
    .directive('negate', [ 
     function() { 
      return { 
       require: 'ngModel', 
       link: function (scope, element, attribute, ngModelController) { 
        ngModelController.$isEmpty = function(value) { 
         return !!value; 
        }; 

        ngModelController.$formatters.unshift(function (value) { 
         return !value; 
        }); 

        ngModelController.$parsers.unshift(function (value) { 
         return !value; 
        }); 
       } 
      }; 
     } 
    ] 
); 

使用方法如下:

<input type="checkbox" negate ng-model="entity.nologin"> 
0

我認爲是最簡單的解決方案,以得到一個複選框選中還是未選中值是通過將NG-INIT指令的複選框輸入元件內部如下:

<input type="checkbox" ng-init="video = false" ng-model="video" > 

這使得複選框的初始值是假的,國家是不受控制的。在提交表單時,如果取消選中該複選框,返回(或控制檯)的值將爲false,而不是「未定義」,否則在檢查時爲true。

,如果你想爲true或false狀態添加定製的值,你可以使用:

ng-true-value="'custom_true value'" 

ng-false-value="'custom_false value'" 

輸入元素中。 像:

<input type="checkbox" ng-init="video = false" ng-model="video" ng-true-value="'custom_true value'" ng-false-value="'custom_false value'"> 
0

我的解決方案很簡單:只需使用NG-真值/NG-假值,並設置假到NG-真實價值和真實的NG-假值這將扭轉功能。

<input type="checkbox" ng-model="<<-- Your Model -->> " ng-true-value="false" 
 
      ng-false-value="true">