简体   繁体   English

重用ng-controller作为单例

[英]Reused ng-controller as singleton

I understand that ng-controller create a new instance of controller. 我知道ng-controller创建了一个新的控制器实例。 How could I reused the controller in different place of my template and keep the same model. 我怎样才能在模板的不同位置重用控制器并保持相同的模型。

I try to find out by myself but I am new in AngularJs and a bit lost... 我试着自己找出来,但我是AngularJs的新手并且有点失落......

See my example in Plunker: http://plnkr.co/edit/VGLEcdlY4IaAJmJPWhQ7?p=preview 请参阅我在Plunker中的示例: http ://plnkr.co/edit/VGLEcdlY4IaAJmJPWhQ7?p = preview

HTML HTML

<body ng-app="app">
    <div ng-controller="test">
        <label ng-click="test()">Test: {{ name }}</label><br/>
        <input type="text" ng-model="name" />
    </div>
    <p>Here some other ng-controller...</p>
    <div ng-controller="test">
        <label ng-click="test()">Test: {{ name }}</label><br/>
        <input type="text" ng-model="name" />
    </div>
</body>

Js JS

angular
.module('app', [])
.controller('test', function($scope) {
    $scope.name = 'hello world';
    $scope.test = function(){ alert('alert'); };
})

The 2 fields are not connected to the same model/scope, how can make this singleton and have the same model for both input. 2个字段没有连接到相同的模型/范围,如何使这个单例和两个输入具有相同的模型。

I had similar case too, and I think the only thing you can do is using service. 我也有类似的情况,我认为你唯一能做的就是使用服务。

angular
.module('app', [])
.controller('test', function($scope, singleton) {
    $scope.name = singleton.getField();


}).service('singleton', function(){
  var field = {value : 'hello world'};


  var getField = function(){
    return field;
  }

  return {
    getField : getField
  };

});

Here I used 'field' as an object because in this case you'll have link to the same object in both controllers. 在这里,我使用'field'作为对象,因为在这种情况下,您将链接到两个控制器中的同一对象。

http://plnkr.co/edit/8yXY2qsIqcBtTqZDUxSa?p=preview http://plnkr.co/edit/8yXY2qsIqcBtTqZDUxSa?p=preview

By far the most simple way is to move the ng-controller attribute up to the parent element: 到目前为止,最简单的方法是将ng-controller属性移动到父元素:

<body ng-app="app" ng-controller="test">
    <div>
        <label ng-click="test()">Test: {{ name }}</label><br/>
        <input type="text" ng-model="name" />
    </div>
    <p>Here some other ng-controller...</p>
    <div>
        <label ng-click="test()">Test: {{ name }}</label><br/>
        <input type="text" ng-model="name" />
    </div>
</body>

Updated Plunker 更新了Plunker

If i whant to use controler as singleton I do some like this(this work for me in angular 1.4.3) 如果我想使用控制器作为单身人士,我会做一些这样的事情(这对我来说是角1.4.3)

(function (app) {
    var AbstractController = app.controllers.AbstractController;
    MessageBoxController.static = {
        options: AbstractController.static.createOptions([
            '$ionicSideMenuDelegate',
            MessageBoxController
        ]),
        pluginFolderName: 'message_box',
        hooks: [
            {hook: 'leftMenu', template: 'message_list.html'},
            {hook: 'topBarLeft', template: 'main.html'}
        ]
    };
    var instance;
    function MessageBoxController() {
        if(instance){
            return instance;
        }
        instance = this;
        var mp = this;
        mp.messagesNb = 0;
        mp.test = 'blabla';
        extend(mp, new AbstractController());
        function _init(params) {
            mp._parentInit(params, MessageBoxController.static.options);
            mp.init();
        }
        mp.init = function () {
            mp.showMsgButton = false;
            mp.toggleLeftMenu = mp.toggleLeftMenu;
            mp.messages = {};
            mp.getMessageCSSClass = mp.getMessageCSSClass;
            mp.clearMsg = mp.clearMsg;
            mp.registerMessageWatching();
        };
        mp.registerMessageWatching = function () {
            mp.unregisterWatchintInterval('MessageBoxController');
            var interval = setInterval(mp.checkMessages, 1000);
            mp.registerWatchingInterval('MessageBoxController', interval);
        };
        mp.checkMessages = function () {
            var messages = mp.getAllMsgs();
            mp.messages = messages;
            var messagesCount = messages.length;
            if (mp.messagesNb === messagesCount) {
                return;
            }
            if (messagesCount > 0) {
                mp.$scope.$apply(function () {
                    mp.showMsgButton = true;
                });
            } else {
                mp.$scope.$apply(function () {
                    mp.showMsgButton = false;
                });
            }
            mp.messagesNb = messagesCount;
        };
        mp.toggleLeftMenu = function () {
            mp.$rootScope.$root.leftMenu = !mp.$rootScope.$root.leftMenu;
            if(mp.$rootScope.$root.leftMenu){
                mp.$rootScope.buff.title = mp.$rootScope.$root.title;
                mp.$rootScope.$root.title = app.l('Messages');
            }else{
                mp.$rootScope.$root.title = mp.$rootScope.buff.title;
            }
        };
        mp.getMessageCSSClass = function(type){
            switch(type){
                case app.messagesTypes.inform:
                    return 'confirm_msg';
                    break;
                case app.messagesTypes.error:
                    return 'error';
                    break;
                case app.messagesTypes.warning:
                    return 'warning';
                    break;
            }
        };
        mp.clearMsg = function(key){
           mp.messages.splice(key, 1);
           mp.messagesNb--;
           if(mp.messagesNb < 1){
               mp.$rootScope.$root.leftMenu = false;
               mp.$rootScope.$root.title = mp.$rootScope.buff.title;
           }
        };
        _init(arguments);
    }
    app.controllers.MessageBoxController = MessageBoxController;
})(deliveryManagerGlobal);

And in template write like this 并在模板中写这样的

<div ng-controller="MessageBoxController as msgBox" class="msg_box">
    <div class="card" ng-repeat="(key, message) in msgBox.messages">
        <div class="item item-text-wrap" ng-class="msgBox.getMessageCSSClass(message.type)">
            {{message.context}}
        </div>
        <div class="close ion-android-close" ng-click="msgBox.clearMsg(key)"></div>
    </div>
</div>

If you will write like this you do not use $scope( angular is create for every ng-controller new scope) and you can use singelton. 如果您将这样写,您不使用$ scope(angular是为每个ng-controller新范围创建的),您可以使用singelton。 sou you can add new dom element with same ng-controller="MessageBoxController as msgBox" and it will use your prev instance. 您可以使用相同的ng-controller =“MessageBoxController as msgBox”添加新的dom元素,它将使用您的prev实例。 For now I have not see collateral bugs in my app structure. 目前我还没有看到我的应用结构中的附带错误。 I have use dinamic hooks managmet so I was needed singleton and this work for me good 我使用dinamic hooks managmet所以我需要单身,这对我来说很好

Think carefully about what you're doing here. 仔细想想你在这里做了什么。 A controller shouldn't hold state. 控制器不应该保持状态。 It should be repeatable and stateless. 它应该是可重复的和无国籍的。 If you want to persist state I suggest you use a service. 如果你想坚持状态我建议你使用服务。 Services are singletons by design. 服务是单身设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM