代码之家  ›  专栏  ›  技术社区  ›  James-Jesse Drinkard

如何使用Angularjs从带有父路由控制器的页面获取数据到自定义指令?

  •  0
  • James-Jesse Drinkard  · 技术社区  · 6 年前

    我使用的是Angularjs 1.4x,我有一个页面,其中有一个控制器声明如下:

    $stateProvider
            .state('myPage', {
                url: '/my-page',
                templateUrl: templateUrl,
                controller: 'searchCtrl', ...
    

    在那个页面上,我有一个名为myDirective的指令,它有一个带有ng click的按钮,该按钮将一些文本作为参数发送回指令控制器。我要做的是,当用户单击按钮,然后调用另一个控制器获取参数值并打开一个模式时,将该参数值返回到指令。

    如果我使用$scope,我可以从searchCtrl中获取值,但是我一直无法找到方法来获取接收参数值的指令。在过去,我会将按钮放在模板中,但这里的按钮已经在myPage.html页面中。

    我现在知道我不能在页面上使用ng控制器,因为它已经有一个来自$route的控制器,它是searchCtrl。那么正确的方法是什么呢?

    plunker :

    <!DOCTYPE html>
    <html>
      <head>
        <script data-require="angular.js@1.4.2" data-semver="1.4.2" src="https://code.angularjs.org/1.4.2/angular.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
      </head>
    
      <body>
        <div id="app" ng-app="app">
        <div ng-controller="myCtrl">
              <my-directive ctrl-fn="ctrlFn"></my-directive> 
            </div>
          </div>
    
      </body>
    </html>
    

    myPage.html页面

    <div>
      <button ng-click="ctrlFn({param: 'hello'})">Click Here</button>
    </div>
    

    // Code goes here
    var app = angular.module('app', []);
    app.controller('myCtrl', function($scope){
    
      $scope.ctrlFn = function(param) {
          console.log("param is: " + JSON.stringify(param));
      };  
    });
    
    function newCtrl($scope) {
      //How can I call this function from inside the directive and pass in param?
      //Do something here
    }
    
    app.directive('myDirective', function() {
      return {
        restrict: 'E',
        scope: {
          ctrlFn: '&'
        },
       templateUrl: "./myPage.html",
        link: function(scope, element, attributes, controller) {
          scope.ctrlFn = scope.ctrlFn();
    
        }
      };
    });
    

    关于如何正确实施这一点有什么想法吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Sean    6 年前

    如果可以将回调函数放入服务中,可以执行以下操作:

    var app = angular.module('app', []);
    app.controller('mainCtrl', function($scope, newCtrl) {
    
      $scope.ctrlFn = function(param) {
        console.log("param is: " + JSON.stringify(param));
        newCtrl.notify(param);
      };
      console.log(" $scope.ctrlFn is: " + JSON.stringify($scope.ctrlFn));
    });
    
    function newCtrl() {
      return {
        notify: notify
      }
    
      function notify(param) {
        console.log("In newCtrl.notify, param is: " + JSON.stringify(param));
      };
    }
    
    app.directive('myDirective', function() {
      return {
        restrict: 'E',
        scope: {
          ctrlFn: '&'
        },
        templateUrl: "./myPage.html",
        link: function(scope, element, attributes, controller) {
          scope.ctrlFn = scope.ctrlFn();
        }
      };
    });
    
    app.factory("newCtrl", newCtrl);
    

    见: https://plnkr.co/edit/5N957XYFPZVndr75lQ8N?p=preview

    如果你需要 $scope

    如果不需要匿名函数 mainCtrl ,您可以更进一步执行以下操作:

    $scope.ctrlFn = newCtrl.notify;
    

    有点复杂(我很抱歉将我所有的params/properties命名为ngModel),但这正是我想要做的,当我想要一个从页面控制器传递数据的指令时,该指令打开一个模式,并且基于用户交互,将通过指令更新回初始控制器/视图的数据(模型)的值更改为:

    1. 我创建一个指令,在该指令上设置 ng-model 我的(主控制器/页面)视图中的属性,指向控制器上的属性 $范围

    2. 指令可以在 隔离范围

    3. 在用户操作中,该指令打开一个模式并通过 resolve bootstrap的属性 modal.open 方法。我通常传入多个值,因此将它们全部放入一个“options”组合参数中。

    4. 然后,模态控制器可以将该值设置到模态视图中(通过模态 $范围 vm ). 通常,我会在模式对话框中加载数据,例如显示一个项目列表供用户选择。

    5. Close 事件/操作,我将值(是否由用户交互更改)返回给调用者[作为指令的控制器],调用者将其设置回指令的[独立的]作用域,该作用域实质上更新主控制器上的属性,因为它是通过 = 价值。

    https://plnkr.co/edit/qAa1pOwigCgJ99Lx6vsj?p=preview