2016-02-25 2 views
0

РЕШЕНИЯ -Угловой директива инъекционной DOM элемент с событием щелчка - решаемые

Спасибо пользователя более на форуме Google показал мне свойство controllerAs для директив. Эта версия теперь работает отлично:

angular 
.module('app') 
.directive('userSearch', userSearch); 

function userSearch($compile){ 

return { 
    controller: function() 
     { 
      this.search = function() { 
       alert('Test'); 
      }; 
     }, 

    link: function (scope, element, attrs) { 

     element.bind('focus', function() { 

      var nextElement = element.parent().find('.openuserdialog').length; 

      if (nextElement === 0) { 

       var btn = '<img src="' + homePath + 'Images/zoomHS.png" ' + 
          'ng-click="userSearch.search()" ' + 
          'class="openuserdialog" />'; 

       element.after($compile(btn)(scope)); 

      } 

     }); 
    }, 
    controllerAs: 'userSearch' 

}; 

}; 

Содержание отредактирован -

Цель состоит в том, чтобы создать директиву, которая может быть прикреплена к текстовому полю, что, когда текстовое поле имеет фокус,/кнопка появится изображение после текстовое поле и событие click/image/button будут запускать функцию, содержащуюся в директиве. Цель состоит в том, чтобы эта функциональность была полностью автономной в директиве, поэтому ее можно легко развернуть на многих страницах или в приложениях.

Изображение/кнопка появляется после текстового поля без проблем, но событие нажатия кнопки не запускает функцию. Я создал plunkr с примером кода.

В строке, строка 15 определяет функцию, называемую «поиск», которая ничего не делает, кроме как вызвать предупреждение. Когда текстовое поле имеет фокус, кнопка отображается как ожидалось, а строка 34 успешно вызывает функцию поиска, что означает, что сама функция работает. Однако событие нажатия кнопки не запускает функцию поиска.

Любая помощь была бы принята с благодарностью!

Оригинальное сообщение:

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

Что я до сих пор делал, это простая html-страница, простой контроллер и простая директива. Когда текстовое поле имеет фокус, изображение выглядит так, как ожидалось. Однако директива ng-click не срабатывает.

Вот HTML:

  <input 
       id="txtAlias" 
       type="text" 
       ng-model="pc.results" 
       user-search /> 

</div> 

Вот контроллер:

angular 
    .module('app') 
    .controller('PeopleController', PeopleController); 

PeopleController.$inject = ['$http']; 

function PeopleController() { 

    var pc = this; 

    pc.results = ''; 

    pc.search = function() { 
     alert('test'); 
    }; 
} 

И это директива:

angular 
    .module('app') 
    .directive('userSearch', userSearch); 

function userSearch($compile) { 

return { 
    restrict: 'EAC', 
    require: 'ngModel', 
    //transclude: true, 
    scope: { 
     //search : function(callerid){ 
     // alert(callerid); 
     //} 
    }, 
    template: "The user's alias is: <b><span ng-bind='pc.results'></span>.", 
    //controller: UserSearchController, 
    link: function (scope, element, attrs) { 
     element.bind('focus', function() { 

      //alert(attrs.id + ' || ' + attrs.userSearch); 

      var nextElement = element.parent().find('.openuserdialog').length; 

      if (nextElement == 0) { 
       var magnifyingglass = $compile('<img src="' + homePath + 'Images/zoomHS.png" ' + 
             'alt="User Search" ' + 
             'ng-click="pc.search("' + attrs.id + '")" ' + 
             'class="openuserdialog">')(scope); 

       element.after(magnifyingglass); 
      } 

     }); 
    } 

}; 

}; 

В настоящее время, я бы счастлив получить предупреждение о стрельбе, либо нажав pc.search в контроллере, либо выполнив поиск в изоляции . До сих пор ни одна из них не работала. Я уверен, что это что-то простое, чего не хватает, но я не могу понять, что. Любая помощь будет оценена.

+0

Если значок увеличительного стекла всегда есть, почему бы просто не сделать его частью шаблона директивы, вместо того, чтобы вставлять его сразу после? – Dave

+0

@ Давай, он не всегда будет там. Предполагается, что разработчик сможет добавить директиву пользовательского поиска в любое текстовое поле, которое может потребовать функции поиска. – johneasley

+0

Ах, и потому, что это texbox, вам нужно поставить увеличительное стекло за его пределы. Рассматривали ли вы создание директивы, которая всегда отображает texbox, и условно отображает увеличительное стекло, если присутствует атрибут пользовательского поиска? – Dave

ответ

0

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

Markup

<input id="txtAlias" 
    type="text" ng-model="pc.results" 
    user-search search="search(id)" /> 

scope: { 
    search: '&' 
} 

Как вы не имеете доступа к родительской области, вы не можете использовать псевдоним контроллера там, как вы используете pc.. Просто используйте следующее без псевдонима. Поэтому директива будет напрямую связывать эти переменные с областью директивы.

template: "The user's alias is: <b><span ng-bind='results'></span>.", 

изменить Также компилировать шаблон

if (nextElement == 0) { 
    var magnifyingglass = $compile('<img src="' + homePath + 'Images/zoomHS.png" ' + 
     'alt="User Search" ' + 
     'ng-click="search({id: ' + attrs.id + '})' + 
     'class="openuserdialog">')(scope); 
    element.after(magnifyingglass); 
} 

Скорее я хотел бы иметь скомпилированный шаблон в качестве части template лишь директивы функции. И я покажу и спрячу его на основе директивы ng-if="expression".

Relative answer

+0

Спасибо, Панкай. Я изменил свойство scope, как вы предложили, и изменил значение ng-click изображения. Без изменений. Изображение появляется, но при нажатии на него ничего не происходит. В конечном счете, нажатие на изображение должно запускать отдельную функцию. На данный момент это будет хорошо, если функция является просто предупреждением. Какие-либо предложения? – johneasley

+0

@ johneasley, это было мое плохое .. Посмотрите на обновленный ответ –

+0

Итак, область действия и свойство ng-click были изменены, как вы предложили. Без изменений. При нажатии на изображение все равно не срабатывает функция или предупреждение. Представленный html показывает следующее в элементе управления изображением: – johneasley

0

Вместо того, чтобы ввести в DOM, а затем пытается подключиться к этим вещам вы просто впрыскиваетесь, завернуть как вход и/значок кнопки поиска в директиве. Вы можете использовать изолированный объем и двухсторонние связывания для подключения ввода и кнопок:

HTML:

<body ng-controller="MainCtrl"> 
    <p>Hello {{name}}!</p> 
    <search-box data="name" search-function="search"></search-box> 
    </body> 

Вот как контроллер и директивы, которые демонстрируют это. Обратите внимание на «=» в изолированной области, создавая двустороннюю привязку к соответствующим атрибутам, когда директива используется в шаблоне.

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    $scope.search= function() { alert('search clicked'); } 
}); 

app.directive('searchBox', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     searchFunction: '=', 
     data: '=', 
    }, 
    template: '<input ng-model="data" /><button ng-click="searchFunction()">Search</button>' 
    } 
}) 

Вы должны иметь возможность легко заменить button элемент с img или то, что душе угодно.

Вот звенеть с предупреждением() для окна поиска, и где печатать в текстовом поле в директиве влияет на соответствующее свойство видимости контроллера: http://plnkr.co/edit/0lj4AmjOgwNZ2DJMSHDj