3

У меня есть директива, которая должна выполнять некоторые манипуляции с DOM на основе результата служебного вызова в контроллере. После такого подход я в настоящее время следующий:Лучший подход для запуска директивы от контроллера

1) Создание объекта запуска в каждой области контроллера, соответствующий каждую директиву в виде - делать Dóm манипуляции при необходимости

2) Создание директивы и сделать манипуляции DOM на основе значения, установленного контроллером;

app.directive("myDirective", function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      attrs.$observe('myDirective', function (value) { 
       if (value === "true") { 
        $(element).text("Scrolled to####" + $(element).data("scroll")); 
       } 

      }); 
     } 
    }; 
}); 

3) Из соответствующего метода контроллера установите значение true, чтобы вызвать функциональные директивы

app.controller("controller1", ["$scope", function ($scope) { 
    $scope.trigger1 = false; 

    $scope.triggerDirective1 = function() { 

     $scope.trigger1 = true; 
    }; 
    $scope.trigger2 = false; 

    $scope.triggerDirective2 = function() { 

     $scope.trigger2 = true; 
    }; 
}]); 

<div id="c1" ng-controller="controller1">Controller 1 
    <br>List 1 
    <div my-directive="{{trigger1}}" data-scroll="20"></div>List 2 
    <div my-directive="{{trigger2}}" data-scroll="30"></div> 
    <button ng-click="triggerDirective1()">Trigger Directive 1</button> 
    <button ng-click="triggerDirective2()">Trigger Directive 2</button> 
</div> 

Полный код здесь - http://jsfiddle.net/qec35dq4/

Я считаю этот подход не так хорошо из-за следующая причина:

1) Будет указано несколько элементов с директивой, прилагаемой

2) Каждый триггер Директивы является независимым. В любое время в действии будет действовать только одна директива. В зависимости от количества директив, я должен отслеживать все триггеры в соответствующем контроллере.

Есть ли лучший способ решить эту проблему, так что можно избежать зависимости от отслеживания этого объекта области триггера в контроллере? Я думал об использовании $broadcast/$emit,$on. Но не думайте, что это будет хорошее решение. Пожалуйста, дайте мне знать ваши мысли.

Заранее спасибо за любую помощь

EDIT:

Новая скрипка - http://jsfiddle.net/86pk8LtL/

изменил пример немного, чтобы отразить больше на то, что я пытаюсь достичь - Там будет несколько списков на страница, на которую будет применена эта директива. Основываясь на некоторой логике из фонового, некоторые элементы должны быть выбраны в списке. После выбора элементов список следует прокручивать так, чтобы отображался первый выбранный элемент (в примере я жестко кодирую прокрутку с использованием атрибутов данных. Но в действительности директива будет выполнять расчет). Цель этой директивы - просто для обработки части «прокрутки для просмотра», поэтому я скептически отношусь к тому, чтобы сохранить для нее свойство scope. Обратите внимание, что текущий подход работает нормально. Просто хочу посмотреть, есть ли какой-нибудь лучший подход к этому.

+0

Я вижу, что вы обновляете некоторые 'result' элемент с текстом принятого в' msg' наряду с директивой. Является ли этот текст статическим для этого триггера? – Arkantos

+0

Пожалуйста, игнорируйте логику внутри директивы. Это просто указывает на то, что директива будет выполнять некоторые манипуляции с DOM при срабатывании. – user700284

+0

Поскольку в любой момент времени активен только один триггер, правильно ли предположить, что другие divs с разными триггерами не будут отображаться? – Arkantos

ответ

0

Я должен был сделать что-то подобное на прошлой неделе. Кросс-элементная директива dom манипуляции может быть сложной, если вы не хотите писать более одной директивы, но когда я это сделал, я искал элементы, которые я хотел по ID. Это избавит вас от необходимости определять методы в области.

<div id="trigger1"></div>List 2 
<div id="trigger2"></div> 
<button my-directive="trigger1" data-scroll="20">Trigger Directive 1</button> 
<button my-directive="trigger2" data-scroll="30">Trigger Directive 2</button> 

И директива.

app.directive("myDirective", function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
       var idElem = document.getElementById(attrs.myDirective); 
       var elementToChange = angular.element(idElem); 
       element.on("click", function(){ 
        elementToChange.text("Scrolled to####" + attrs.dataScroll); 
       }); 
      }); 
     } 
    }; 
}); 
1

AngularJS на самом деле не использует DOM-запросы, подобные библиотекам, управляемым событиями. Я бы предложил использовать выборка контроллера. Поскольку Angular поддерживает стандарты OOP, попробуйте вложить свои контроллеры, объем дочерних контроллеров наследуется от родительских контроллеров, что означает, что вы можете наблюдать за состоянием того, какой элемент запускается. Взгляните на этот базовый пример. http://jsfiddle.net/qec35dq4/3/ Кроме того, я бы предложил вместо наблюдения атрибутов передать модель в область действия директивы. Это поможет вам избежать наблюдения за изменением атрибута.

Меньше всего, но не последний, вам действительно не нужно следить за изменением атрибута элемента. Он доступен через attrs вашей директивы:

app.directive("myDirective", function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      attrs.$observe('myDirective', function (value) { 
       if (value === "true") { 
        $("#result").text(attrs.msg); 
       } 

      }); 
     } 
    }; 
}); 

EDIT Вот demo на основе вашего последнего JSFiddle.

0

Я хотел бы отметить две вещи

  1. AngularJs не о DOM манипулированию.

  2. Рабочая концепция директивы, она должна быть чисто независимой от контроллера и всего, должна работать на всех местах.

На мой взгляд, срабатывание директивы должно быть основано на данных.

Так что не будет проблемой в использовании нескольких директивы в одном представлении, если они срабатывают по данным

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