这是一个指令,应根据传入数据
更改元素的颜色和文本function colorStatus() {
return {
restrict: 'AE',
scope: {
status: '@'
},
link: function (scope, element) {
let status = +scope.status;
switch (status) {
case 0:
element.text(' ');
element.css('color', '#FFFFFF');
break;
case 1:
element.text('Correct!');
element.css('color', '#4CAF50');
break;
case 2:
element.text('Error!');
element.css('color', '#F44336');
break;
case 3:
element.text('Waiting...');
element.css('color', '#FF9800');
break;
}
}
};
}
最初,它从控制器接收已解析的数据。
这是HTML:
<color-status status="{{vm.status}}"></color-status>
<button ng-click="vm.changeStatus()"><button>
这是来自控制器的功能:
vm.changeStatus = changeStatus;
vm.status = chosenTask.status; // It equals 0 in the received data
function changeStatus() {
vm.status = 1;
}
我希望指令的文字和颜色会改变,但这不会发生。我的错误在哪里?
答案 0 :(得分:0)
您遇到的问题是您在link
功能中设置了元素的文字和颜色。这意味着当你的指令实例化并进行初始化时,link
函数将被执行,但它将被执行一次。当status
的值发生变化时,您不会处理这些更改以反映您的元素。因此,您应该将$onChanges()
函数添加到您的指令并处理这些更改。
function StatusController($element) {
this.$element = $element;
this.status = 0;
}
StatusController.mapper = [
{ text: ' ', color: '#FFFFFF' },
{ text: 'Correct!', color: '#4CAF50' },
{ text: 'Error!', color: '#F44336' },
{ text: 'Waiting...', color: '#FF9800' },
}];
StatusController.prototype.setStatus = function(status) {
var statusObj = StatusController.mapper[+status];
this.$element
.text(statusObj.text)
.css('color', statusObj.color);
}
StatusController.prototype.$onInit = function() {
// this.status is now populated by the supplied attribute value
this.setStatus(this.status);
}
StatusController.prototype.$onChanges = function(changes) {
if (changes.status && !changes.status.isFirstChange()) {
this.setStatus(this.status);
}
}
var StatusDirective = {
restrict: 'AE',
controller: StatusController,
scope: true,
bindToController: {
status: '@'
}
};
angular.module('someModule')
.directive('colorStatus', function() { return StatusDirective; });
但除此之外,我还建议您使用ng-bind
或{{...}}
设置元素的文本以将该值放入。指令可以填充其公共属性,并在HTML中使用它们和CSS一起。如果可能的话,不从AngularJS代码中操纵DOM元素总是更明智。
function StatusController($element) {
this.$element = $element;
this.status = 0;
this.text = '';
this.name = '';
}
StatusController.mapper = [
{ text: ' ', name: '' },
{ text: 'Correct!', name: 'correct' },
{ text: 'Error!', name: '#error' },
{ text: 'Waiting...', name: 'pending' },
}];
StatusController.prototype.setStatus = function(status) {
var statusObj = StatusController.mapper[+status];
this.text = statusObj.text;
this.name = statusObj.name;
}
StatusController.prototype.$onInit = function() {
// this.status is now populated by the supplied attribute value
this.setStatus(this.status);
}
StatusController.prototype.$onChanges = function(changes) {
if (changes.status && !changes.status.isFirstChange()) {
this.setStatus(this.status);
}
}
var StatusDirective = {
restrict: 'AE',
controller: StatusController,
controllerAs: 'colorStatus',
scope: true,
bindToController: {
status: '@'
}
};
angular.module('someModule')
.directive('colorStatus', function() { return StatusDirective; });
然后在你的模板中写这样使用它:
<color-status status="{{vm.status}}" ng-class="colorStatus.name" ng-bind="colorStatus.text"></color-status>
这将为您提供更多模板灵活性。除了在控制器中设置文本之外,您可以只使用类名并使用伪类向元素添加文本,但是您可以这样做,因此<color-status>
指令的每个实例都可以以相同的状态显示值。