2015-12-03 5 views
0

У меня проблема, когда я пытаюсь связать объект javascript в атрибуте директивы.AngularJS привязывает объект javascript к атрибуту директивы

У меня есть контроллер, в котором я делаю запрос $ http.get для службы api rest, я получаю некоторые данные, среди которых строка JSON, представляющая маршрут для холста карты.

.controller('myController', ['$scope', '$http', function($scope,$http) { 
    $http.get(endpointUrl) 
     .success(function(data){ 
      if(data.status == 'ok'){ 
       $scope.itinerary = angular.fromJson(data.itinerary); 
      } 
     }); 
}]); 

Если я вхожу $ scope.itinerary в консоли я вижу, что это действительный JavaScript Object

{"origin":"Piazza Adua, Firenze","destination":"Galleria degli Uffizi, Firenze","waypoints":[{"location":"Fiesole, Firenze","stopover":true},{"location":"Piazza Santa Croce, Firenze","stopover":true}],"optimizeWaypoints":false,"travelMode":"DRIVING"} 

мне нужно, чтобы связать этот объект в атрибуте директивы.

.directive('map', function(){ 
    return { 
     restrict: 'E', 
     scope: { 
      myItinerary: "=" 
     }, 
     templateUrl: 'templates/directive/map.html', 
     link: function(scope,el,attrs) { 
      console.log(attrs); 
     } 
    } 
}); 

Это HTML

<map my-itinerary="itinerary"></map> 

Когда я вхожу AttrS внутри функции директива ссылка атрибут myItinerary является строка «маршрут», а не объект, как я бы ожидать. Я попытался интерполировать маршрут с {{}}, но, как и следовало ожидать, это приведет к синтаксической ошибке. Я также попытался переключить '=' на '@' и привязать строку json вместо javascript-объекта, но значение attrs.myItinerary внутри директивы - пустая строка. Я видел много примеров для привязки объекта к директиве, и никто не имеет проблемы с тем же подходом, который я использовал. Поскольку я начал использовать угловые недавно, я хотел бы знать, ошибочен ли мой подход или почему он не работает. Заранее благодарим за помощь.

+0

'attrs' будет только когда-либо быть строковым значением всех атрибутов. '$ scope.myItinerary' будет связанным значением. Все связанные значения доступны в методе 'link' в вашей' $ scope' – ste2425

+0

Я попытался зарегистрировать scope.myItinerary внутри функции ссылки, но результат тот же: значение представляет собой строку «маршрут», а не объект, который я сохранил в $ scope.itinerary в контроллере – berno

+0

Если вы выполните 'console.log (scope.myItinerary)', вы получите объект JavaScript. –

ответ

0

Оригинальный выпуск

Когда вы связываете то директивы это связанное значение доступно на объекте $scope. Не объект attrs.

Так в контроллере $scope.controllerParam = 10

и реализован в представлении <my-directive input="controllerParam"></my-directive>

Вы могли бы иметь директиву разметки, как так содержание

.directive('myDirective', function() { 
    return { 
     restrict: E, 
     scope: { 
      input: '=' 
     }, 
     link: function ($scope, e, attrs) { 
      console.log($scope.input); //Will log 10 
      console.log(attrs.input); //Will log string controllerParam 
     } 
    } 
}); 

Обновление в вашем Link

Этот из ваших комментариев о данных, полученных из A ПИ.

Ваша функция связи запускается один раз, когда ваша директива запускается. Вот почему, когда вы console.log вашей области, значение myItinerary не определено, поскольку вызов AJAX не вернулся в этот момент. Если вы должны положить console.log в тайм-аут, он будет работать с возвратом запроса AJAX и значением, обновленным посредством привязки данных в этот момент.Однако это ужасная идея для работы с динамическим контентом.

Часы

Если вам нужно выполнить некоторую логику связанной переменной в функции связи вы можете поставить часы на нем, так что, если она изменяется внутри или за пределами вашей директивы обработчик часы будут стрелять.

$scope.$watch('myItinerary', function(newValue, oldValue) { 
    console.log(newValue, oldValue); 
}); 

Однако, если ваш добавив много из них, они могут прийти на спектакль хит, как каждый часы оценивается каждый раз, когда цикл дайджеста запускается, Plüss обработки тот факт, что они могут быть вызваны изменениями внутри или за пределами вашей директивы может с чем трудно бороться.

Услуги

Вообще говоря все ваши AJAX-запросы должны быть определены в службе и ввели в то, что когда-либо нуждается в них. Поэтому, если директива имеет одну цель, вполне возможно, что она может сделать этот запрос сама, введя службу непосредственно в нее.

Привязка функции Ваша директива также потенциально может выставить функцию, с которой может связываться ваш контроллер. Когда ваш контроллер имеет данные, он может вызывать эту функцию, передавая ее данные.

//View 
<my-directive update="update"></my-directive> 

//in controller simply do 
$scope.update('new data'); 

//directive 

.directive('myDirective', function() { 
    return { 
     restrict: E, 
     scope: { 
      update: '=' 
     }, 
     link: function ($scope, e, attrs) { 
      $scope.update = function (d) { 
       console.log(d); 
      } 
     } 
    } 
}); 

Вы должны быть осторожны, если вы пытаетесь вызвать связанную функцию, которая не была обновлена ​​еще или если директива имеет то, как дополнительную. В любом случае связанная переменная в контроллере не определена.

Из них все, на мой взгляд, обслуживание лучше. Возврат к часам, когда услуга не подходит. Я избегаю раскрытия функций, поскольку он просто чувствует себя неловко для меня, но это возможно. Чтобы быть справедливым, я очень редко нуждаюсь в использовании часов в материалах, которые должен был делать ive.

Извините за эссе

+0

Большое спасибо за ваш полный ответ. – berno

+1

Я думаю, что у вас есть опечатка во втором примере, директива должна быть объявлена ​​как ''. Если не указано явно, имя атрибута будет иметь имя переменной области видимости в определении вашей директивы. – Max

+0

@Max yup, ваш правильный. Я его отредактировал. – ste2425

0

Я создал sample для hypen (-).

Вы должны убедиться, что вы используете

scope: { 
    myItinerary: "=myItinerary" 
} 

Вы можете обратиться к последнему, например, под Creating a Directive that Wraps Other Elements секции в angularjs

+0

Как показал ste2425, это проблема времени. Команда console.log запускается до ответа HTTP-запроса с данными. Странно, что если я сделаю console.log (scope) внутри функции директивной ссылки, свойство myItinerary правильно задано с obj ... по этой причине я не думал, что это может быть проблема синхронизации – berno

+0

@berno, I обновили образец – Priya

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