当我的指令控制器 运行 使用 "Controller As" 语法时未评估数据
Data not evaluated when my directive controller run using "Controller As" syntax
我创建了一个简单的 Angular JS 指令:
- 它收到一个数字 X[=43=]
- 它计算X的下一个和前一个数字
这里是指令代码
(function() {
'use strict';
angular
.module('main')
.directive('myDirective', myDirective);
/** @ngInject */
function myDirective() {
return {
bindToController: true,
controller: MyController,
controllerAs: 'vm',
restrict: 'E',
scope: {
number: '<'
},
templateUrl: 'my-directive.template.html',
};
}
/** @ngInject */
function MyController($scope, $timeout) {
var vm = this;
// calculate(); // previous and next = NaN
// $timeout(calculate, 1); // Works
vm.watch = $scope.$watch('vm.number', calculate); //Works
function calculate() {
vm.previous = vm.number - 1;
vm.next = vm.number + 1;
vm.watch();
}
}
})();
我是这样称呼它的
<my-directive number="7"></my-directive>
我的问题是:
- 控制器运行时,传递给指令的数字尚未计算
经过研究,我找到了 2 个解决方案,但它们看起来不太好:
- 在 MyController
中使用 $timeout
服务
- 在 MyController
中使用 $scope.$watch
服务
我认为如果评估数据需要更长的时间,解决方案(1)有时可能会下降。
由于不需要看数据,采用方案(2)我在函数calculate
执行完后就把watch去掉了,但是这里用watch感觉不对
那么,有更好的解决方案吗?或者解决方案 (2) 就可以了?
问题出在你的模块声明中。
这个
angular
.module('main')
应该是这个
angular
.module('main', [])
声明新模块时需要[requires]参数。
正如用户 Claies 所建议的那样,我为此创建了一个组件,并且效果很好。
这里是组件声明
(function() {
'use strict';
angular
.module('main')
.component('myComponent', {
templateUrl: 'my-component.template.html',
controller: MyController,
controllerAs: 'vm',
bindings: {
number: '<',
goNext: '&',
goPrevious: '&'
}
});
/** @ngInject */
function MyController() {
var vm = this;
vm.$onInit = onInit;
vm.$onChanges = onNumberChange;
vm.onNext = onNext;
vm.onPrevious = onPrevious;
function onInit() {
calculate();
}
function onNumberChange(changesObj) {
if (changesObj.number) {
calculate();
}
}
function onNext() {
vm.goNext();
}
function onPrevious() {
vm.goPrevious();
}
function calculate() {
vm.previous = vm.number - 1;
vm.next = vm.number + 1;
}
}
})();
为了测试组件的 $onChanges
功能,我添加了一个 add
和一个 subtract
操作。
下面是我在 HTML 页面中使用该组件的方式
<my-component number="vm.number" go-next="vm.goNext()" go-previous="vm.goPrevious()"></my-component>
我做的完整例子可以在这个Plunker
中找到
我创建了一个简单的 Angular JS 指令:
- 它收到一个数字 X[=43=]
- 它计算X的下一个和前一个数字
这里是指令代码
(function() {
'use strict';
angular
.module('main')
.directive('myDirective', myDirective);
/** @ngInject */
function myDirective() {
return {
bindToController: true,
controller: MyController,
controllerAs: 'vm',
restrict: 'E',
scope: {
number: '<'
},
templateUrl: 'my-directive.template.html',
};
}
/** @ngInject */
function MyController($scope, $timeout) {
var vm = this;
// calculate(); // previous and next = NaN
// $timeout(calculate, 1); // Works
vm.watch = $scope.$watch('vm.number', calculate); //Works
function calculate() {
vm.previous = vm.number - 1;
vm.next = vm.number + 1;
vm.watch();
}
}
})();
我是这样称呼它的
<my-directive number="7"></my-directive>
我的问题是:
- 控制器运行时,传递给指令的数字尚未计算
经过研究,我找到了 2 个解决方案,但它们看起来不太好:
- 在 MyController 中使用
- 在 MyController 中使用
$timeout
服务
$scope.$watch
服务
我认为如果评估数据需要更长的时间,解决方案(1)有时可能会下降。
由于不需要看数据,采用方案(2)我在函数calculate
执行完后就把watch去掉了,但是这里用watch感觉不对
那么,有更好的解决方案吗?或者解决方案 (2) 就可以了?
问题出在你的模块声明中。
这个
angular
.module('main')
应该是这个
angular
.module('main', [])
声明新模块时需要[requires]参数。
正如用户 Claies 所建议的那样,我为此创建了一个组件,并且效果很好。
这里是组件声明
(function() {
'use strict';
angular
.module('main')
.component('myComponent', {
templateUrl: 'my-component.template.html',
controller: MyController,
controllerAs: 'vm',
bindings: {
number: '<',
goNext: '&',
goPrevious: '&'
}
});
/** @ngInject */
function MyController() {
var vm = this;
vm.$onInit = onInit;
vm.$onChanges = onNumberChange;
vm.onNext = onNext;
vm.onPrevious = onPrevious;
function onInit() {
calculate();
}
function onNumberChange(changesObj) {
if (changesObj.number) {
calculate();
}
}
function onNext() {
vm.goNext();
}
function onPrevious() {
vm.goPrevious();
}
function calculate() {
vm.previous = vm.number - 1;
vm.next = vm.number + 1;
}
}
})();
为了测试组件的 $onChanges
功能,我添加了一个 add
和一个 subtract
操作。
下面是我在 HTML 页面中使用该组件的方式
<my-component number="vm.number" go-next="vm.goNext()" go-previous="vm.goPrevious()"></my-component>
我做的完整例子可以在这个Plunker
中找到