Использование директивы для присоединения объекта с доступом к области видимости к элементу HTML

0

Я хочу создать два поля поиска A и B. Когда пользователь вводит значение в A, они получают некоторые результаты в <ul></ul> из которых они могут выбирать. Теперь, если пользователь выбирает результат из A (ng-click on <li>), я хочу, чтобы этот результат также был выбран для B (позвоните в эту помощь ввода). Значение должно храниться контроллером в поле B до тех пор, пока пользователь не захочет использовать поле B также. Тем не менее, A и B являются обеими директивами, так как я должен повторно использовать их несколько раз. Кроме того, я хочу, чтобы вспомогательная функция ввода была (набором) директив (ы), так как мне нужно снова использовать их с другими полями формы. Что там, где вещи становятся более сумасшедшими. В принципе, мне трудно передавать данные между всеми областями, которые создаются с использованием разных директив и контроллеров. Может быть, мне следует использовать совершенно другой подход?

Это директива, которая дает мне неприятности. Я установил $scope.$watch на ctrl.selection но он не будет срабатывать (plnkr):

[...]
function assistReceiver() {
    return {
        require: "^inputAssist",
        link: function (scope, element, attrs, ctrl) {
            console.log("receiver: " + ctrl.selection);
            console.log(ctrl);
            scope.$watch(ctrl.selection, function (newVal, oldVal) {
                console.log(ctrl);
                console.log("receiver: " + newVal);
                attrs.scSelection = newVal;
                attrs.scModel = newVal;
            });
        }
    };


}

В этом контроллере создается ctrl.selection:

[...]
function InputAssistController(inputAssist) {
    var vm = this;
    vm.selection = "";
}

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

[...]
function assistSender() {
    return {
        require: "^inputAssist",
        link: function (scope, element, attrs, ctrl) {
            console.log(scope);
            console.log(ctrl);
            scope.$watch(attrs.scWatch, function (newVal, oldVal) {
                if (newVal !== oldVal) {
                    ctrl.selection = newVal;
                }
            });
        }
    };


}

Здесь вы можете увидеть, какие атрибуты используются. Код для других директив находится в плункере:

<!DOCTYPE html>
<html>
...
<body ng-app="searchbox">

<input-assist>
    <search-box assist-sender sc-watch="sCtrl.inputModel"></search-box>
    <search-box assist-receiver sc-selection="sCtrl.selectedLens" sc-model="sCtrl.inputModel"></search-box>
</input-assist>


</body>
</html>

У вас есть идея, почему он не стреляет? Использую ли я совершенно бесполезный подход? Я пробовал разные подходы, но думаю, что на этот раз я действительно близок.

1 ответ

2
Лучший ответ

Я не знаю, правильно ли я понял вашу проблему: вы хотите изменить значение на основе другого значения и хотите использовать для этого директиву, потому что изменение всегда одно и то же и может происходить в разных местах.

Тогда вам нужна только одна директива:

angular
.module('searchbox')
    .directive('react', react);

react.$inject = [];
function react(){
  return {
    restrict: 'A',
    scope: {
      react: '=',
      affect: '='
    },
    link: function (scope, element, attrs) {
      scope.$watch('react', function(newVal) {
        scope.affect = newVal + 'some change';
      });
    }
  }
}

А затем предположим, что у вас есть два выпадающих списка:

<select ng-model="ctrl.selection1"> .... </select>
<select ng-model="ctrl.selection2" react="ctrl.selection1" affect="ctrl.selection2>...</select>

Редактировать:

Помните, что вы можете передавать объекты и даже функции в свою ограниченную область действия:

<select ng-model="ctrl.complexObject.selection1"> .... </select>
<input type="text" ng-model="ctrl.complexObject.textInput">
<select ng-model="ctrl.selection2" react="ctrl.complexObject" affect="ctrl.selection2" affect-function="ctrl.affect(obj)">...</select>

и директива

return {
    restrict: 'A',
    scope: {
      react: '=',
      affect: '=',
      affectFunction: '&'
    },
    link: function (scope, element, attrs) {
      scope.$watch('react', function(newVal) {
        if(scope.affectFunction) {
           scope.affect = scope.affectFunction({obj: newVal});
        }
        else { //default behaviour
           scope.affect = newVal.selection1 + newVal.textInput;
        }
      });
    }
  • 0
    Хм, я думаю, я мог обдумать эту проблему ^ ^ Спасибо!
  • 0
    Я пытался применить ваш ответ к моей проблеме, но на самом деле все оказалось не так просто. Итак, проблема в том, что мне нужно это для работы в разных случаях, включая случай, когда есть два поля поиска. В случае с полями выбора это работает нормально, но нет, если у меня есть два поля ввода плюс несортированный список результатов, к которым также прикреплено событие click. Не могли бы вы взглянуть на поршень? Я даже не уверен, что использую правильный подход.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню