使用 ng-model 避免组件指令中的 $digest 延迟
Use ng-model to avoid $digest delay in Component Directives
如何在 angularJs
的指令中调用控制器的任何函数
当指令的绑定值发生变化时,我正在尝试调用父控制器的函数,这与指令没有太大关系。
我一直在查看堆栈中的问答,但它们都与将值从指令传递到控制器有关,这不是我的情况。
我以为我的情况很普遍,情况是:
在循环中显示复杂对象,属性 中的一个对象绑定在指令上。当 属性 发生变化时,对更新后的复杂对象执行一些操作。
但是在我的代码中,它打印旧对象值而不是更新后的值。我的猜测是我的更新函数在 $digest 进程完成之前被调用。
有什么建议吗?
plunker 示例: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-model
和 ng-change
:
更新值
<my-directive ng-model="item.value" ng-change="mc.update(item)">
</my-directive>
JS:
$ctrl.value++;
$ctrl.ngModelCtrl.$setViewValue($ctrl.value);
通过这种方法,ngModelController will update the value before calling ng-change。
The Demo
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>
I don't quite understand those two lines:
require: {ngModelCtrl: 'ngModel'}
. does ngModelCtrl works as renaming 'ngModel' so that it can be used in directive's controller?
value: '<ngModel'
. what does '<'
do?
require: {ngModelCtrl: 'ngModel'}
将 ng-model
控制器 API 绑定到名称为 ngModelCtrl
.
的指令控制器
scope: {value: '<ngModel'}
创建 ng-model
属性到名称为 value
.
的控制器的单向绑定
有关详细信息,请参阅
- AngularJS Comprehensive API Reference - require
- AngularJS Comprehensive API Reference - scope
- AngularJS Developer Reference - Component-based application architecture
- AngularJS Developer Reference - Intercomponent Communication
- AngularJS ngModelController API Reference - $setViewValue
使用 ng-model
可以与 ngFormController 的验证 API 集成。可以创建具有多个输入的自定义表单组件。
有关详细信息,请参阅
如何在 angularJs
的指令中调用控制器的任何函数当指令的绑定值发生变化时,我正在尝试调用父控制器的函数,这与指令没有太大关系。
我一直在查看堆栈中的问答,但它们都与将值从指令传递到控制器有关,这不是我的情况。
我以为我的情况很普遍,情况是: 在循环中显示复杂对象,属性 中的一个对象绑定在指令上。当 属性 发生变化时,对更新后的复杂对象执行一些操作。
但是在我的代码中,它打印旧对象值而不是更新后的值。我的猜测是我的更新函数在 $digest 进程完成之前被调用。
有什么建议吗?
plunker 示例: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-model
和 ng-change
:
<my-directive ng-model="item.value" ng-change="mc.update(item)">
</my-directive>
JS:
$ctrl.value++;
$ctrl.ngModelCtrl.$setViewValue($ctrl.value);
通过这种方法,ngModelController will update the value before calling ng-change。
The Demo
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>
I don't quite understand those two lines:
require: {ngModelCtrl: 'ngModel'}
. does ngModelCtrl works as renaming 'ngModel' so that it can be used in directive's controller?value: '<ngModel'
. what does'<'
do?
require: {ngModelCtrl: 'ngModel'}
将 ng-model
控制器 API 绑定到名称为 ngModelCtrl
.
scope: {value: '<ngModel'}
创建 ng-model
属性到名称为 value
.
有关详细信息,请参阅
- AngularJS Comprehensive API Reference - require
- AngularJS Comprehensive API Reference - scope
- AngularJS Developer Reference - Component-based application architecture
- AngularJS Developer Reference - Intercomponent Communication
- AngularJS ngModelController API Reference - $setViewValue
使用 ng-model
可以与 ngFormController 的验证 API 集成。可以创建具有多个输入的自定义表单组件。
有关详细信息,请参阅