2015-03-23 6 views
0

Я новый в AngularJS. Я попытался создать директиву с опцией transclude=true, но она, похоже, разбивает $ scope. Вот мой код:

<!DOCTYPE html> 
<html ng-app="myApp"> 
    <head> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script> 
    <script type="text/javascript"> 
     var app = angular.module('myApp', []); 

     app.controller('myController', ['$scope', function($scope){ 
     $scope.myText = 'Hello'; 

     $scope.facility = null; 
     $scope.facilities = [ 
      {id:1, name:'One'}, 
      {id:2, name:'Two'}, 
      {id:3, name:'Three'} 
     ]; 

     $scope.query = function(){ 
      console.log($scope.facility, $scope.myText); 
     } 
     }]); 

     app.directive('ohMy', function(){ 
     return { 
      transclude: true, 
      template: function(){ 
      return '<form novalidate><div ng-transclude></div></form>'; 
      } 
     } 
     }); 

    </script> 
    </head> 
    <body> 
    <div ng-controller="myController"> 
     <oh-my> 
     <input type="text" ng-model="myText"></input> 
     <div>{{myText}}</div> 
     <select ng-change="query()" ng-model="facility" ng-options="f.name for f in facilities"></select> 
     </oh-my> 
    </div> 
    </body> 
</html> 

Когда я изменил значение текстового поля (MYTEXT), текст внутри DIV на следующем из текстового поля показывает обновленное значение, как я ожидал. Но не тогда, когда я играю с раскрывающимся списком, - что консоль браузера всегда показывает значения по умолчанию.

Когда я удалил эту директиву, тогда все будет хорошо.

Что я делаю неправильно в создании директивы? Любая идея исправить это?

- ОБНОВЛЕНИЕ -

После прибегая к помощи на некоторое время, я нашел эту ссылку: AngularJS transclude but keep the directive's scope и попытаться понять его, то я изменил код директивы, чтобы быть как это:

app.directive('ohMy', function(){ 
    return { 
     transclude: true, 
     template: function(){ 
     return '<form novalidate><div ng-transclude></div></form>'; 
     }, 
     link: function(scope, element, attrs, ctrl, transclude) { 
     transclude(scope, function(clone) {    
      element.children(0).empty().append(clone); 
     }); 
     } 
    } 
    }); 

И он работает так, как я ожидал сейчас. Но любое лучшее решение?

+4

Да, это правило точки. Ваша модель 'объект' должна быть вложенной в объект. Директива создает дочернюю область, и в этот момент вы работаете с двумя разными свойствами '$ scope.facility', потому что это значение является примитивным. Если вы выполняете 'foo.facility', то дочерняя область наследует' foo', а затем 'объект' должен быть одинаковым для обоих. – m59

+0

Спасибо, m59! Он работает с точкой. Но как вы сказали, что это «правило», так это то, чего мы не можем избежать? Я имею в виду, что модель внутри этой директивы должна быть вложенным объектом? – Adiono

+0

Некоторые люди притворяются, что наследование $ scope не существует и помещает области выделения во все директивы, а затем просто передает данные явно директивам. – m59

ответ

-1

Вы можете попробовать получить модель от $ родительского объема:

 <oh-my> 
     <input type="text" ng-model="$parent.myText"></input> 
     <div>{{myText}}</div> 
     // get model from $parent scope. 
     <select ng-change="query()" ng-model="$parent.facility" ng-options="f.name for f in $parent.facilities"></select> 
     </oh-my> 

Ссылка демо: http://plnkr.co/edit/as7dSEybw7PWB24JlPWp?p=preview

+0

Спасибо, но нет :) - Я не буду изменять часть HTML, ни часть контроллера, я хочу исправить эту директиву. – Adiono

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