2016-03-10 4 views
1

В приведенном ниже коде вы можете увидеть, что у меня есть компонент счетчика, который запускает события с шагом и декрементом, и они привязаны к выводимому выводу. Эти события находятся на $ rootScope, чтобы их можно было услышать на другом компоненте, который тоже работает. Что не работает, это привязка данных к моему наблюдателю. Если вы посмотрите на консоль, она правильно принимает событие и его данные и даже обновляет свойство сообщения, но оно не обновляется в представлении. Что дает? Ниже мой код:Обязательная привязка данных компонента AngularJS не работает должным образом

script.js

angular.module('testApp', []).component('counter', { 
bindings: { 
    input: '<', 
    output: '&' 
}, 
controller: function ($rootScope, $attrs) { 
    this.output = $attrs.input; 

    this.increment = function increment() { 
     this.output++; 
     console.log("event from counter fired"); 
     $rootScope.$emit('eventfromcounter', 'increment'); 

    } 

    this.decrement = function decrement() { 
     this.output--; 
     console.log("event from counter fired"); 
     $rootScope.$emit('eventfromcounter', 'decrement'); 

    } 

}, 
template: function ($element, $attrs) { 
    return [ 
    '<input type="text" ng-model="$ctrl.output">', 
    '<button type="button" ng-click="$ctrl.decrement();">-</button>', 
    '<button type="button" ng-click="$ctrl.increment();">+</button>', 
    ].join(''); 
} 
}).component('watchercomponent', { 
    bindings: { 
     message : '&' 
    }, 
    controller: function ($rootScope, $attrs) 
    { 
     this.message = 'waiting for event'; 
     $rootScope.$on('eventfromcounter', function (event, args) 
     { 
      console.log("recieved at anothercomponent : " + event.name + " : " + args); 
      this.message = args; 
      console.log("message : " + this.message); 
     }); 
    }, 
    template: function($element, $attrs) 
    { 
     return [ 
      '<br/><span>watchercomponent : {{$ctrl.message}}</span>' 
     ].join(''); 
    } 
}); 

index.html

<html> 

    <head> 
    <script src="angular.min.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body> 
    <div ng-app = "testApp"> 
     <counter input="3"></counter> 
     <watchercomponent></watchercomponent> 
    </div> 
    </body> 

</html> 

Plunker здесь.

Также есть отличная практика $ rootScope для обмена событиями/данными между компонентами? Если бы никто не мог указать мне правильное направление?

Благодаря

+2

Используйте $ широковещательный вместо $ испускают https://plnkr.co/edit/f1jL6HtDyXrt0O0KpD9W?p=preview. Для обмена данными между директивами используйте службу, а не $ rootScope. –

+0

Не транслируется только хуже (дизайн мудрого) испускать? Также это не решает проблему привязки данных, которая не работает с компонентом watcher. – user2119597

ответ

2

Ваша проблема основана на использовании this. В JavaScript контекст внутри каждой функции отличается, поэтому значение this ссылается на что-то другое. Вот почему вы хотите сохранить ссылку на свой контроллер this с помощью var ctrl = this;.

JS

angular.module('testApp', []).component('counter', { 
    bindings: { 
     input: '<', 
     output: '&' 
    }, 
    controller: function ($rootScope, $attrs) { 
     this.output = $attrs.input; 

     this.increment = function increment() { 
      this.output++; 
      console.log("event from counter fired"); 
      $rootScope.$broadcast('eventfromcounter', 'increment'); 

     } 

     this.decrement = function decrement() { 
      this.output--; 
      console.log("event from counter fired"); 
      $rootScope.$broadcast('eventfromcounter', 'decrement'); 

     } 

    }, 
    template: function ($element, $attrs) { 
     return [ 
     '<input type="text" ng-model="$ctrl.output">', 
     '<button type="button" ng-click="$ctrl.decrement();">-</button>', 
     '<button type="button" ng-click="$ctrl.increment();">+</button>', 
     ].join(''); 
    } 
}).component('watchercomponent', { 
    controller: function ($rootScope, $attrs) 
    { 
     var ctrl = this; //Keep a reference to controller's context 

     ctrl.message = 'waiting for event'; 
     $rootScope.$on('eventfromcounter', function (event, args) 
     { 
      console.log("recieved at anothercomponent : " + event.name + " : " + args); 
      ctrl.message = args; //Use controller's context, not function context 
      console.log("message : " + ctrl.message); 
     }); 
    }, 
    template: function($element, $attrs) 
    { 
     return [ 
      '<br/><span>watchercomponent : {{$ctrl.message}}</span>' 
     ].join(''); 
    } 
}); 

Рабочая plunkr: https://plnkr.co/edit/v4VgggsOx1xWsdRnI8hU?p=preview

Смежные вопросы