我试图在AngularJs中创建一个通知系统,就像这里使用的通知一样。当有新评论,回答等时。存档图标会显示一个带有活动数量的红色标记,当我点击它时,它会打开一个包含最后通知的框。
为此,我构建了这个简单的指令来动态加载templateUrl:
HTML:
<li test-alert ref="msg">
<i class="fa fa-envelope-o"></i>
</li>
<li test-alert ref="bell">
<i class="fa fa-bell-o"></i>
</li>
指令:
angular
.module('agApp')
.directive('testAlert', testAlert)
;
/* @ngInject */
function testAlert() {
var templateA = '<div>Test template A</div>';
var templateB = '<div>Test template B</div>';
return{
restrict: 'A',
scope: {
ref: '@'
},
link: function(scope,element,attrs,controller){
scope.showAlert = false;
element.on("click", function() {
if (scope.ref == 'bell') {
scope.showAlert = true;
element.append(templateA);
scope.$apply();
} else {
scope.showAlert = true;
element.append(templateB);
scope.$apply();
};
console.log(scope.ref);
});
element.addEventListener("keyup", function(e) {
if (e.keyCode === 27) {
scope.showAlert = false;
}
});
}
};
}; //end test alert
但我有些问题......
我的主要目标是创建一个与stackOverflow中的通知系统类似的通知系统,这是最好的方法吗?我应该使用控制器吗?
关闭机制我在妈妈家里使用。它可以工作,但也许可以改进。
run.js
angular
.module('agApp')
.run(runApp);
/* @ngInject */
function runApp($rootScope) {
document.addEventListener("keyup", function(e) {
if (e.keyCode === 27) {
$rootScope.$broadcast("escapePressed", e.target);
};
});
document.addEventListener("click", function(e) {
$rootScope.$broadcast("documentClicked", e.target);
});
}; //end run
controller.js
$rootScope.$on("documentClicked", _close);
$rootScope.$on("escapePressed", _close);
function _close() {
$scope.$apply(function() {
vm.closeAlert();
});
};
由于我无法将其用作指令,因此我在控制器内部移动了打开/关闭功能。但它可以以任何其他方式使用,只要它有效,就没有问题。
答案 0 :(得分:1)
首先,关键事件仅触发可能获得焦点的文档和元素。
指令非常适合您需要多次使用的东西。但即使您将通知系统实施为指令并仅使用一次 - 您也会将其隔离,这通常很好。
很难在不知道更多的情况下提供最佳解决方案,但这里有一个将消息和通知实现为一个指令的示例:
app.directive('notifications',
function() {
return {
restrict: 'E',
templateUrl: 'template.html',
scope: {},
link: function(scope, element, attrs, controller) {
scope.viewModel = {
showTemplateA: false,
showTemplateB: false
};
scope.toggleTemplateA = function() {
scope.viewModel.showTemplateA = !scope.viewModel.showTemplateA;
scope.viewModel.showTemplateB = false;
};
scope.toggleTemplateB = function() {
scope.viewModel.showTemplateB = !scope.viewModel.showTemplateB;
scope.viewModel.showTemplateA = false;
};
}
};
});
它只包含显示和隐藏模板的逻辑。该指令使用如下所示的模板:
<div>
<i class="fa fa-envelope-o" ng-click="toggleTemplateA()"></i>
<div ng-show="viewModel.showTemplateA">
Template A
</div>
<br>
<i class="fa fa-bell-o" ng-click="toggleTemplateB()"></i>
<div ng-show="viewModel.showTemplateB">
Template B</div>
</div>
模板使用ng-show
和ng-click
绑定到我们的范围函数。通过这种方式,我们让Angular完成工作并且不必混淆element.append
等。
用法:
<notifications></notifications>
演示: http://plnkr.co/edit/8M1D5uENjpDoIbb1ZuMR?p=preview
要实现关闭机制,您可以将以下内容添加到指令中:
var close = function () {
scope.$apply(function () {
scope.viewModel.showTemplateA = false;
scope.viewModel.showTemplateB = false;
});
};
$document.on('click', close);
$document.on('keyup', function (e) {
if (e.keyCode === 27) {
close();
}
});
scope.$on('$destroy', function () {
$document.off('click', close);
$document.off('keyup', close);
});
请注意,您现在必须将$document
注入指令:
app.directive('notifications', ['$document',
function($document) {
在切换功能中,您可以调用stopPropagation()
以防止在单击图标时执行全局关闭处理程序(在此示例中可能不需要,但很有必要。可能希望它在实际模板中未来?):
scope.toggleTemplateA = function($event) {
$event.stopPropagation();
和
ng-click="toggleTemplateA($event)"