我有一个项目列表,每当添加新项目时,我都需要在导航栏中收到一条消息(说明项目已添加!)。
函数addItem()(在Add Item按钮上单击ng)在ItemFactory中,从那里我似乎无法广播它。
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body ng-app="MyApp" ng-controller="MainCtrl">
<div>{{ text }}
<nav class="navbar navbar-inverse" ng-controller="NavCtrl">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">List of items | {{ alertItemAdded }}</a>
</div>
<form class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" class="form-control" ng-model="newItem" placeholder="Add an item">
</div>
<button type="submit" class="btn btn-primary" ng-click="addItem(newItem)">Add Item</button>
</form>
</div>
</nav>
<div class="container" ng-controller="ContentCtrl">
<div class="row">
<div class="col-xs-12">
<form class="form-inline">
<div class="form-group">
<input type="text" class="form-control" ng-model="newItem" placeholder="Add an item">
</div>
<button type="submit" class="btn btn-primary" ng-click="addItem(newItem)">Add Item</button>
</form>
<br />
<br />
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div ng-repeat="item in items">
<form class="form-inline">
<div class="form-group">
<div>{{ item }}</div>
</div>
<button type="button" class="btn btn-default btn-s" ng-click="removeItem($index)">Remove Item</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
angular.module('MyApp',[]);
angular.module('MyApp').controller('MainCtrl', function($scope, ItemFactory){
$scope.text = "Text from the Main Controller";
$scope.addItem = function(newItem){
ItemFactory.addItem(newItem);
}
});
angular.module('MyApp').controller('NavCtrl', function($scope){
// $on
$scope.$on('itemAdded', function(event, data){
$scope.alertItemAdded = data;
});
});
angular.module('MyApp').controller('ContentCtrl', function($scope, ItemFactory){
$scope.items = ItemFactory.getItem();
$scope.removeItem = function($index){
ItemFactory.removeItem($index);
}
});
angular.module('MyApp').factory('ItemFactory', function(){
var items = [
'Item 1',
'Item 2',
'Item 3'
];
return {
getItem : function() {
return items;
},
addItem : function(item){
items.push(item);
// $broadcast
$scope.$broadcast('itemAdded', 'Item added!');
},
removeItem : function($index){
items.splice($index, 1);
}
};
});
答案 0 :(得分:2)
您可以将$ rootScope注入工厂并使用$ broadcast。
angular.module('MyApp').factory('ItemFactory', ["$rootScope", function($rootScope){
var items = [
'Item 1',
'Item 2',
'Item 3'
];
return {
getItem : function() {
return items;
},
addItem : function(item){
items.push(item);
// $broadcast
$rootScope.$broadcast('itemAdded', 'Item added!');
},
removeItem : function($index){
items.splice($index, 1);
}
};
}]);
答案 1 :(得分:1)
这是一个干净利落的解决方案。
请参阅此plunker
让我解释一下这一切是如何运作的。
您的邮件如下所示:
<span ng-if="alertItemAdded.recentAdd">Item added !</span>
只有在&#34; alterITemAdded.recenAdd&#34;是真的。如果需要,您将使用此功能使消息消失。
你的工厂现在看起来像这样:
angular.module('MyApp').service('ItemService', function(){
var service = {};
//I'll always wrap my data in a sub object.
service.notification = {};
service.notification.recentAdd=false;
service.items = {};
service.items.list = [
'Item 1',
'Item 2',
'Item 3'
];
service.items.addItem = function(item){
service.items.list.push(item);
service.notification.recentAdd=true;
console.log(service);
}
service.items.removeItem = function($index){
service.items.list.splice($index, 1);
}
return service;
});
我使用的是服务而不是工厂。但几乎没有区别,只是品味问题。
这是您的控制器
angular.module('MyApp').controller('MainCtrl', function($scope, ItemService){
$scope.text = "Text from the Main Controller";
});
angular.module('MyApp').controller('NavCtrl', function($scope, ItemService){
//IMPORTANT POINT : I bind it the sub object. Not to the value. To access the value i'll use $scope.alterItemAdded.recentAdd
$scope.alertItemAdded = ItemService.notification;
//I don't have to redeclare the function. I just bind it to the service function.
$scope.addItem = ItemService.items.addItem;
});
angular.module('MyApp').controller('ContentCtrl', function($scope, ItemService){
$scope.items = ItemService.items.list;
$scope.addItem = ItemService.items.addItem;
$scope.removeItem = function($index){
ItemService.items.removeItem($index);
}
});
重点:
我总是将我的变量绑定到子对象。为什么?事实上,如果我这样做 $ scope.alertItemAdded = ItemService.notifications.recentAdd
当我在我的服务中做这样的事情时
service.notifications.recentAdd = true;
它将创建一个新变量并将引用放入service.notifications.recentAdd。 $ scope.alertItemAdded绑定到上一个引用,不会看到更新。
这样做:
$scope.alterItemAdded = ItemService.notification
并使用ng-if子句中的值或其他任何内容。我阻止引用链接中断。如果我在服务中
service.notification.recentAdd = true
我将为&#34; recentAdd&#34;创建一个带有新引用的新var。但我对&#34;通知&#34;保持相同的参考。将保留控制器中的绑定,并在视图中更新值recentAdd。
如果您有更多问题可以随意提问。
答案 2 :(得分:-1)
你没有将$ scope注入工厂,实际上你不能使用$ rootScope
答案 3 :(得分:-2)
$broadcast
从上到下,因此您应该使用$rootScope
对其下方的所有$broadcast
元素执行$scope
。
在工厂中注入$rootScope
$ rootScope。$ broadcast('itemAdded,'Item added!')