【问题标题】:Use directive with different controllers in AngularJS?在 AngularJS 中使用具有不同控制器的指令?
【发布时间】:2017-01-09 20:02:28
【问题描述】:

我已经为一个搜索框创建了一个指令,我想将它用于不同的视图。这是指令 -

angular.module('jobSeekerApp')
  .directive('searchBoxDirective', function () {
    return {
      restrict: 'E',
      templateUrl: 'templates/searchbox-template.html',
    };
  });

指令模板 -

<span class="searchButton"><i class="fa fa-search fa-2x"></i></span>
<input ng-change="search()" ng-model="searchTerm" ng-keydown="deleteTerm($event)" type="text" id="search-box" style="width: 0px; visibility:hidden;"/>

我想在两个看起来像这样的视图上使用这个指令 -

查看 1 -

<div class="panel panel-default companies" ng-repeat="company in companies.companiesList">
    <div class="panel-heading text-center"><a ng-href="/companies/{{company.id}}" class="hvr-sink"><h3 class="well">{{company.company_name}}</h3></a></div>
    <div class="panel-body text-center flexcontainer">
        <div>Location: {{company.location}}</div>
        <div>Founded In: {{company.founded_year}}</div>
        <div ng-if="company.opening">Opening: Yes</div>
        <div ng-if="!company.opening">Opening: No</div>
        <div>Number Of Openings: {{company.no_openings}}</div>
    </div>
</div>

查看 2 -

<div class="panel panel-default jobs" ng-repeat="job in jobs.jobsList">
    <div class="panel-heading text-center"><a href="{{job.career_url}}" target='_blank' class="hvr-sink"><h3 class="well">{{job.job_name}}</h3></a></div>
    <div class="panel-body text-center flexcontainer">
        <div>Company: {{job.company_name}}</div>
    </div>
</div>

如您所见,我在视图中使用别名 companiesjobs,因此我的指令无法影响它包含的视图。如果我使用 companiesjobs在我的模板中,它工作正常。因此,例如,如果将模板更改为 -

<span class="searchButton"><i class="fa fa-search fa-2x"></i></span>
<input ng-change="companies.search()" ng-model="companies.searchTerm" ng-keydown="companies.deleteTerm($event)" type="text" id="search-box" style="width: 0px; visibility:hidden;"/>

然后它适用于与companies 控制器关联的视图,同样适用于jobs

如何将指令与相应的控制器实例一起使用? 谢谢。

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    为搜索创建一个简单的视图

    创建它自己的控制器

    该控制器在服务中搜索记录并将数据放入服务变量中

    this.searchResult = [];
    this.search = function(searchText){
        // code to search
        this.searchResult = Result;    
    }
    

    现在,无论您想在哪里使用此结果,请在当前控制器中的此服务变量上使用监视,例如:

    $scope.$watch(function() { return servicename.searchResult ; }, function(newVal, oldval) { 
       if(newval != oldval){
           $scope.data = servicename.searchResult;
           /* Do the rest of stuff */
       }
    }, true);
    

    【讨论】:

    • 除非绝对必要,否则我强烈反对使用 $watch。如果您对它们失去控制并且不是最佳实践,它们可能会很密集。
    【解决方案2】:

    由于搜索功能是异步的,我建议避免使用ng-change 来调用它。而是在搜索图标上使用ng-click

    <span class="searchButton" ng-click="$ctrl.searchFn()">
        <i class="fa fa-search fa-2x"></i>
    </span>
    <input ng-model="$ctrl.searchTerm" type="text" id="search-box">
    

    在指令中,使用隔离作用域和bindToController

    app.directive('searchBoxDirective', function () {
        return {
          restrict: 'E',
          scope: { 'searchTerm': "=",
                   'searchFn': "&"
                 },
          controller: function () {},
          controllerAs: '$ctrl',
          bindToController: true,
          templateUrl: 'templates/searchbox-template.html'
        };
    });
    

    用法

    <search-box-directive search-term="companies.searchTerm"
                          search-fn="companies.search()" >
    </search-box-directive>
    
    <search-box-directive search-term="jobs.searchTerm"
                          search-fn="jobs.search()" >
    </search-box-directive>
    

    search-term 属性创建从父范围到指令隔离范围的双向绑定。 search-fn 属性创建从父作用域到隔离作用域的表达式绑定。

    【讨论】:

    • 谢谢,这就是我一直在尝试做的。我使用 ng-change 是因为我想在用户开始输入时立即显示结果,而不是先单击按钮。另外,我没有分别传递search-termsearch-fn,而是传递了作用域中的完整对象并像ng-model="$ctrl.obj.searchTerm"一样使用它。只是好奇我如何传递一个接受像ng-keydown="companies.deleteTerm($event)"这样的事件的函数?
    【解决方案3】:

    使用隔离范围并将搜索词显式传递给您的指令。比如:

    angular.module('jobSeekerApp')
      .directive('searchBoxDirective', function () {
        return {
          restrict: 'E',
          scope: {
            searchTerm: '=' <-- you can use '@' if you don't need two-way binding
          },
          templateUrl: 'templates/searchbox-template.html',
        };
      });
    

    您没有显示您实际使用指令的位置,但您将通过属性传递范围属性(这是在 &lt;div&gt; 上使用您的指令):

    <div search-box-directive search-term="companies.searchTerm"></div>
    

    【讨论】:

      猜你喜欢
      • 2015-01-11
      • 2014-12-24
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多