使用 ng-model 避免组件指令中的$digest延迟



如何在 angularJs 中的指令中调用控制器的任何函数

当指令的绑定值发生变化时,我正在尝试调用父控制器的函数,该函数与指令没有太大关系。

我一直在浏览堆栈中的问答,但所有这些都与将值从指令传递到控制器有关,这不是我的情况。

我认为我的情况很常见,情况是: 在循环中显示复杂对象,这是指令上对象绑定的属性之一。当属性发生更改时,对更新的复杂对象执行某些操作。

但是在我的代码中,它打印的是旧的对象值,而不是更新的对象值。我的猜测是我的更新函数在进程完成之前被调用$digest。

有什么建议吗?

普伦克示例:https://plnkr.co/edit/bWGxEmJjNmiKCkRZTqOp?p=preview

下面是控制器代码:

var $ctrl = this;
$ctrl.items = [
{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 30}
];
$ctrl.update = function(item){
//trying to update item after changing
console.log("updated item is: " + angular.toJson(item));
};

这是指令代码:

var controller = function($scope){
var $ctrl = this;
$ctrl.clicked = function(){
$ctrl.value = $ctrl.value + 1;

//calling the bind on-change function defined in controller
$ctrl.onChange();
}
};
return {
restrict: 'E',
scope: {
value: '=',
onChange: '&'
},
controller: controller,
controllerAs: '$ctrl',
bindToController: true,
templateUrl: 'directive.html'
};

Html看起来像这样:

<div ng-repeat="item in mc.items">
<my-directive value="item.value" on-change="mc.update(item)"></my-directive>
</div>

和指令模板:

<button type="button" ng-click="$ctrl.clicked()">{{$ctrl.value}}</button>

您是正确的,在进程完成之前调用更新函数$digest

一种方法是使用ng-modelng-change更新值:

<my-directive ng-model="item.value" ng-change="mc.update(item)">
</my-directive>

.JS:

$ctrl.value++;
$ctrl.ngModelCtrl.$setViewValue($ctrl.value);

使用这种方法,ngModelController 将在调用 ng-change 之前更新值。

演示

angular.module('myApp', [])
.controller('myController', function(){
var $ctrl = this;
$ctrl.items = [
{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 30}
];
$ctrl.update = function(item){
//trying to update item after changing, but here it prints out old item instead of updated item.
console.log("updated item is: " + angular.toJson(item));
};

})
.directive('myDirective', function(){
var controller = function(){
var $ctrl = this;
$ctrl.clicked = function(){
$ctrl.value++;
$ctrl.ngModelCtrl.$setViewValue($ctrl.value);
console.log("calling clicked in directive and value is ", $ctrl.value);
}
};
return {
restrict: 'E',
require: {ngModelCtrl: 'ngModel'},
scope: {
value: '<ngModel',
},
controller: controller,
controllerAs: '$ctrl',
bindToController: true,
template: `<button type="button" ng-click="$ctrl.clicked()">
{{$ctrl.value}}
</button>`
};
});
<script src="//unpkg.com/angular@1.6/angular.js"></script>
<body ng-app='myApp' ng-controller="myController as mc">
<div ng-repeat="item in mc.items">
id={{item.id}}
<my-directive ng-model="item.value" ng-change="mc.update(item)">
</my-directive>
</div>
</body>


我不太明白这两行:

  1. require: {ngModelCtrl: 'ngModel'}ngModelCtrl 是否可以重命名"ngModel",以便它可以在指令的控制器中使用?
  2. value: '<ngModel''<'做什么?

require: {ngModelCtrl: 'ngModel'}ng-model控制器 API 绑定到名为ngModelCtrl的指令控制器。

scope: {value: '<ngModel'}创建ng-model属性到名为value的控制器的单向绑定。

有关详细信息,请参阅

  • AngularJS 综合 API 参考 - 需要
  • AngularJS 综合 API 参考 - 范围
  • AngularJS 开发人员参考 - 基于组件的应用程序架构
  • AngularJS 开发人员参考 - 组件间通信
  • AngularJS ngModelController API 参考 - $setViewValue

Usingng-model可以与 ngFormController 的验证 API 集成。可以创建具有多个输入的自定义表单组件。

有关详细信息,请参阅

  • AngularJS 开发人员指南 - 表单 - 实现自定义表单控件(使用ngModel(
  • AngularJS ngFormController API 参考

最新更新