Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 角度:如何从工厂播放?_Angularjs - Fatal编程技术网

Angularjs 角度:如何从工厂播放?

Angularjs 角度:如何从工厂播放?,angularjs,Angularjs,我有一个项目列表,每当添加新项目时,我需要在导航栏中获得一条消息(说项目已添加!) 函数addItem()(ng单击Add Item按钮)位于ItemFactory中,从那里我似乎无法播放它 <!doctype html> <html> <head> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.

我有一个项目列表,每当添加新项目时,我需要在导航栏中获得一条消息(说项目已添加!)

函数addItem()(ng单击Add Item按钮)位于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);
        }
    };

});

{{text}}
添加项
添加项


{{item}} 删除项目 角度模块('MyApp',[]); 角度.module('MyApp').controller('MainCtrl',function($scope,ItemFactory){ $scope.text=“来自主控制器的文本”; $scope.addItem=函数(newItem){ ItemFactory.addItem(新项); } }); 角度.module('MyApp')。控制器('NavCtrl',函数($scope){ //美元 $scope.$on('itemsadded',函数(事件、数据){ $scope.alertItemAdded=数据; }); }); 角度.module('MyApp').controller('ContentCtrl',function($scope,ItemFactory){ $scope.items=ItemFactory.getItem(); $scope.removietem=函数($index){ ItemFactory.removeItem($index); } }); angular.module('MyApp').factory('ItemFactory',function(){ 可变项目=[ “项目1”, “项目2”, “项目3” ]; 返回{ getItem:function(){ 退货项目; }, 附加项:功能(项目){ 项目。推送(项目); //$broadcast $scope.$broadcast('itemsadded','itemsadded!'); }, removeItem:函数($index){ 项目.拼接($索引,1); } }; });
您可以将$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);
        }
    };

}]))

$broadcast
自上而下,因此您应该使用
$rootScope
对其下方的所有
$scope
元素执行
$broadcast

  • 在工厂中注入
    $rootScope

  • $rootScope.$broadcast('itemsadded',itemsadded!')


您没有向工厂注入$scope,实际上您也不能使用$rootScope来代替

这里有一个干净的解决方案

看到它在这里面工作了吗

让我解释一下这一切是如何运作的

您的消息如下所示:

<span ng-if="alertItemAdded.recentAdd">Item added !</span>
我用的是服务而不是工厂。但这几乎没有区别,只是口味的问题

这是你的控制器

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
我将创建一个新的var,其中包含对“recentAdd”的新引用,但对“notification”保留相同的引用。控制器中的绑定将被保留,并且视图中的值recentAdd将被更新


如果您有更多问题,请随时提问。

在工厂中导入$rootScope并从此处进行广播?这是一个非常糟糕的广播用例。为什么人们如此喜欢广播……实际上我不建议在工厂里使用$rootScope。“有更干净的方法可以做到这一点。”冈崎骏完全同意。需要使代码可维护,而不仅仅是运行。我正在使用plunker为您提供一个干净的解决方案。我欣赏并理解您的干净解决方案。尽管如此,我还是给了Tom最好的答案,因为我是AngularJS的初学者,Tom的答案更简单(我现在在现有代码中很容易使用)。但我知道您的答案更高级,我将在将来尝试开始使用您的方法。@M4i4没有问题,请随意选择最能满足您需求的人。无论如何,不建议使用$rootScope。注意不要经常使用它,它应该适合你;)我的答案并不特别先进。这是基本的角度服务/工厂用例,了解这一点将在将来为您节省时间。
service.notification.recentAdd = true