每次自定义指令选择更改时,Angularjs都会调用控制器方法

时间:2015-04-02 10:32:58

标签: angularjs select controller action directive

我为select组件编写了一个自定义指令。我面临的问题是simpleComboSelectionChanged()打印上一个选定的值而不是当前值。请告诉我这是什么问题。

指令&控制器:

.directive('simpleSelect', [function($compile) {
    return {
      restrict: 'E',
      transclude: true,
      require: '^ngModel',
      scope:{
    	  id: '@',
    	  ngModel: '=',
    	  items: '=',
    	  ngChange: '&'
      },
      // linking method
	  link: function(scope, element, attrs) {
		  scope.updateModel = function()
	      {
			  scope.ngChange();
	      };
	    }, 
      template:'<select class="form-control" id="id" ng-model="ngModel" ng-selected="ngModel" ng-options="Type.type as Type.name | translate for Type in items"'+
      'ng-change="updateModel()"></select>'
    };
  }])



.controller('ComboTemplateCtrl', ['$scope', function($scope) {
	   $scope.ComboItems = [{type:1, name:"Combo.Item1", isSet:false},
	   	    		        {type:2, name:"Combo.Item2", isSet:false},
	   	    		        {type:3, name:"Combo.Item3", isSet:false},
	   	    		        {type:4, name:"Combo.Item4", isSet:false},
	   	    		        {type:5, name:"Combo.Item5", isSet:false}
	   	    	      	   ];
	   $scope.simpleSelectValue = $scope.ComboItems[0].type;
	  	  
	   $scope.simpleComboSelectionChanged = function(){
		   console.log("Selected Item is :", $scope.simpleSelectValue);
		   
	   };
  }])
<simple-select id="simpleSelectTest" 
               ng-model="simpleSelectValue" items="ComboItems" 
               ng-change="simpleComboSelectionChanged()"></simple-select>

1 个答案:

答案 0 :(得分:0)

发生这种情况的原因是因为您绑定到ngModel而非require: "ngModel"并使用ngModelController API对其进行修改。 (事实上​​,您使用require,但实际上并未使用。您也没有使用此处不需要的transclude

内部ngModel - 绑定变量 - scope.ngModel - 更改为当前选定的项目,然后内部ng-change被触发,调用外部ng-change },尝试读取绑定到ng-model属性 - $scope.simpleSelectValue的外部变量。但是$scope.simpleSelectValue尚未更改 - 这将发生在稍后会发生的$watch上。

重点是 - 这不是ngModel的用法。

ngModel是自定义输入控件作者(如您自己)可用于与其他ngModel兼容指令(例如formng-required,{集成的指令{1}}和其他自定义指令),可以验证,转换或只是监听输入值的更改。

由于您正在构建自定义输入控件(即使您在封面下使用内置控件),您需要支持自己的ng-change

以下概述了如何做到这一点:

ngModel
需要渲染时会触发

.directive('simpleSelect', function($compile) { return { restrict: 'E', require: 'ngModel', scope: { id: '@', items: '=', }, link: function(scope, element, attrs, ngModel) { ngModel.$render = function(){ scope.selectedValue = ngModel.$viewValue; }; scope.onChange = function(){ ngModel.$setViewValue(scope.selectedValue); }; }, template: '<select class="form-control" id="id" ng-model="selectedValue"' + 'ng-options="Type.type as Type.name for Type in items"' + 'ng-change="onChange()">' + '</select>' }; }); (例如,当模型值发生变化时) - 您需要在此处设置绑定到内部ngModel.$render的值 - 甚至不需要直接DOM操作。

当输入指令从用户接收输入时,将调用

ng-model。同样,由于您使用的是现有输入指令ngModel.$setViewValue,因此您可以依赖其<select>

您还会注意到不再需要拥有自己的ng-change。这是ng-change支持的价值 - 您的指令的使用者可以像对待任何其他指令一样对待您的输入控件,包括对ngModel的支持。

详细了解custom input controls