1

我正在使用自定義的角度表單驗證來驗證基於字段的字段,該字段的值和下拉列表中的選定值。我在頁面上使用同一段代碼(因此也使用相同的指令)兩次。所以我可以做這個重用,我試着發送一個指令的參數。這一切工作正常。但是,當創建子範圍時,它會將我的雙向綁定拆分爲fruit.costAngularJS:在創建新的子作用域時在指令中破壞了2-way綁定

Here is an example fiddle

我在做什麼錯?我希望所有的驗證工作都一樣,但也保留了雙向綁定。這裏是我的小提琴代碼的副本:

JS

function MainCtrl($scope){ 
    $scope.localFruits = [ 
     {name: 'banana'}, 
     {name: 'orange'}, 
     {name: 'grape'} 
    ]; 
    $scope.fruits = [ 
     {name: 'banana'}, 
     {name: 'orange'}, 
     {name: 'grape'} 
    ]; 
    $scope.costRequired = [ 
     'local', 
     'overseas' 
    ]; 
    $scope.selectedCostRequired = ''; 
} 

angular.module('test', []).directive('customRequired', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     scope: { 
      requiredWhenKey: '=', 
      cost: '=' // I think the problem is here?? Can't figure out how to pass the property I want to bind to 
     }, 
     link: function(scope, elem, attrs, ctrl) { 
      //console.log(scope); 
      function isValid(value) { 
       if (scope.$parent.selectedCostRequired === scope.requiredWhenKey) { 
        return !!value; 
       } 
       return true; 
      } 

      ctrl.$parsers.unshift(function(value) { 
       var valid = isValid(value); 
       scope.$parent.subForm.cost.$setValidity('customRequired', valid); 
       return valid ? value : undefined; 
      }); 

      ctrl.$formatters.unshift(function(value) { 
       scope.$parent.subForm.cost.$setValidity('customRequired', isValid(value)); 
       return value; 
      }); 

      scope.$watch('$parent.$parent.selectedCostRequired', function() { 
       scope.$parent.subForm.cost.$setValidity('customRequired', isValid(ctrl.$modelValue)); 
      }); 
     } 
    }; 
}); 

HTML

<div ng-app="test" ng-controller="MainCtrl"> 
<form name="form"> 
    Which grouping is required? <select name="costRequired" ng-model="selectedCostRequired" ng-options="t for t in costRequired"></select> 
    <h2>Local</h2> 
    <div ng-repeat="fruit in localFruits" ng-form="subForm"> 
     {{fruit.name}}: <input name="cost" ng-model="fruit.cost" required-when-key="'local'" custom-required/> bound value is: [{{fruit.cost}}] 
     <span class="error" ng-show="subForm.cost.$error.customRequired">Required</span> 
    </div> 
    <h2>Overseas</h2> 
    <div ng-repeat="fruit in fruits" ng-form="subForm"> 
     {{fruit.name}}: <input name="cost" ng-model="fruit.cost" required-when-key="'overseas'" custom-required/> bound value is: [{{fruit.cost}}] 
     <span class="error" ng-show="subForm.cost.$error.customRequired">Required</span> 
    </div> 
    <div ng-show="form.$invalid" class="error">some form error(s) still exist</div> 
    <div ng-show="!form.$invalid" class="okay">form looks good!</div> 
</form> 
</div> 
+0

小提琴似乎在工作,你還想做什麼? – sh0ber

+0

@ sh0ber問題是雙向綁定不能保持原始範圍是最新的。我可以看到我的問題是如何令人困惑的...我已經更新了小提琴以更清晰一點 –

+0

我不完全確定代碼中發生了什麼,但是您是否嘗試過使用'= attributeToBindTo'而不是'= '在你的指示範圍內?如果沒有,請參閱http://docs.angularjs.org/guide/directive,滾動到'Directive Definition Object'下的'scope' – sh0ber

回答

2

使用ng-model與創建相同的元素doesn't work上的分離範圍指令。

我建議要麼不創建新的範圍,要麼使用scope: true

這裏是不創建一個新的作用域一個簡單的例子:由於required-when-key屬性只是一個字符串

<form name="form"> 
    <div ng-repeat="fruit in localFruits"> 
     {{fruit.name}}: 
     <input ng-model="fruit.cost" required-when-key="local" custom-required/> 
     bound value is: [{{fruit.cost}}] 
    </div> 
</form> 

function MyCtrl($scope) { 
    $scope.localFruits = [ 
     {name: 'banana'}, 
    ]; 
} 
app.directive('customRequired', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function(scope, elem, attrs, ctrl) { 
      console.log(attrs.requiredWhenKey); 
     } 
    }; 
}); 

fiddle

,你可以得到該值使用attrs.requiredWhenKey

如果您不創建新的範圍,您還應該能夠刪除指令中的大部分$parent查找。

+0

完美!我沒有意識到這種屬性對我來說是可用的。對於其他人看這個答案,這裏是我更新小提琴使用馬克的建議:http://jsfiddle.net/cmontgomery/mEvZd/ –