#angularjs #angularjs-directive #openlayers-3
#angularjs #angularjs-директива #openlayers-3
Вопрос:
Я пытаюсь заставить директиву Angular 1.5 работать внутри ng-repeat
для a table
. Несколько вещей, которые мне нужно сделать (и, пожалуйста, если я иду по этому совершенно неправильному пути, дайте мне знать):
1) Обновляйте html всякий раз, когда предоставляются новые результаты. Самое главное, что функция link вызывается один раз с пустым результатом и больше никогда не вызывается. Итак, моя таблица пуста. Всегда.
2) Внутри «шаблона» директивы я ссылаюсь на имя контроллера и метод, который является связью типов. Это «правильный» способ сделать это?
Вот мои фрагменты кода…
module-a.view.html:
<table>
<tr ng-repeat="(ii,result) in moduleACtrl.results">
<td>This is a normal TD</td>
<td-result result="{{result}}" ctrlName="moduleACtrl"></td-result>
</tr>
</table>
ОБНОВЛЕНО
common.td-result.directive.js
(function(){
'use strict';
/* global angular */// ESLINT
angular.module('common').directive('tdResult',Directive);
Directive.$inject = ['$compile'];
function Directive($compile){
return {
restrict : 'E',
scope : {
result : '@',
ctrlName : '@'
},
template: '<td>{{result.prop1}}</td>
<td>{{result.prop2}}</td>
<td>{{result.prop3}}</td>
<td><div ng-click="ctrlName.doSomething()">Something Goes Here {{ctrlName}}</div></td>'
};
}
})();
Прочитав ряд связанных вопросов по StackOverflow и повторно просмотрев документацию по директивам Angular, я не могу понять, как делать то, что я хочу.
Общий контекст, который привел меня сюда, заключается в том, что у меня есть карта OpenLayers 3, отображающая данные результата из запроса. У меня есть результирующие данные на карте, которые интерактивно отображаются при нажатии на них, например: http://openlayers.org/en/latest/examples/getfeatureinfo-image.html
Разница, однако, в том, что я использую Angular 1.5. У меня есть модуль с контроллером и view, в котором размещена карта. У меня есть другой ModuleCommon, в котором находится служба, которая обрабатывает создание объекта map и передает его ModuleA.controller (или любому контроллеру, которому нужен картографический сервис). Итак, теперь мне нужно создать интерфейс для картографического сервиса, который может в общем виде обрабатывать отображение данных любому клиенту, который хочет отобразить указанные данные.
Комментарии:
1. вы вставляете внутри элемента директивы, чтобы это было
<td><td></td></td>
недопустимо. Честно говоря, если у вас есть известное количество свойств, я не вижу никакой пользы даже в создании шаблона директивы для этого2. также для 2-сторонней привязки в области видимости вам нужно использовать
'='
not'@'
, и наблюдение будет автоматическим3. Итак, изначально это был просто html в ng-repeat, и все было хорошо. Но потом я понял, что мне нужен этот фрагмент <td>s где-то еще, но не ng-repeat . Итак, я подумал, давайте сделаем это директивой. Но, может быть, я должен просто повторить этот код? Не уверен, какой сейчас лучший вариант.
4. в большинстве случаев это был бы хороший подход, но элементы таблицы очень специфичны для разрешенных дочерних элементов
5. Вы могли бы повторить
<tbody>
вместо<tr>
, что может помочь
Ответ №1:
Я решил, что все это плохая идея и что мне нужно отступить назад. Во-первых, объект map не должен отвечать за отображение данных. Карта отвечает за обработку события ‘singleclick’ и предоставление мне функции.
Итак, я решил, что контроллер, который создает экземпляр объекта map через картографический сервис, будет просто отвечать за создание и отправку обратного вызова объекту map, чтобы объект map знал, чего хочет его клиент, одним щелчком мыши. Ответственность за GetFeature лежит на объекте карты, а за то, что делать с идентификатором функции, отвечает клиент (т. Е. Контроллер).
Ух ты!
Код карты:
map.on('singleclick',function(event){
map.forEachFeatureAtPixel(event.pixel,function(feature){
callback(feature.getId());
});
});
Код контроллера:
...
function mapCallback(someId){
var elem = angular.element('#info');
if ( someId === undefined ) {
elem.slideUp(); // Hide element
} else {
for (var data, ii = 0, len = vm.dataList.length; ii < len; ii ) {
data = vm.dataList[ii];
if ( someId === data.property ) {
vm.currentData = data;
$scope.$apply();
elem.slideDown(); // Show element
break;
} else {
elem.slideUp(); // Hide element
}
}
}
}
...
1) Карта отделяется от данных, относящихся к объекту.
2) Контроллер управляет тем, что происходит, когда карта выбирает свои данные.
3) HTML-код остается в templateUrl связанного компонента контроллера, где ему и место!