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

How to get data from a page with a parent route controller to a custom directive using Angularjs?

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

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

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

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

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

这是我的代码,但我没有 ui-router,但我不知道这是否重要,plunker:

Index.html

<!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>

script.js

// 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();

    }
  };
});

关于如何正确实施这个的任何想法?

如果您愿意将回调函数放在服务中,您可以这样做:

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);

(不过我不会真的称它为 newCtrl,因为它现在是一项服务)。

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

如果您需要服务中的$scope,您可以将其作为参数传入。

如果你不需要mainCtrl中的匿名函数,你可以更进一步:

$scope.ctrlFn = newCtrl.notify;

编辑:

有点复杂(我为我所有的 params/properties 命名为 ngModel 道歉),但这是我倾向于做的,当我想要一个从页面控制器,然后该指令打开一个模式,并根据用户交互,将通过指令更新回初始 controller/view:

的数据(模型)的值更改
  1. 我创建了一个指令,我在我的(主 controller/page)视图中将 ng-model 属性 设置为 属性控制器 $scope.

  2. 指令可以在隔离范围上访问(读取和写入)这个值,然后可以在模板中使用它。

  3. 在用户操作时,指令打开模态并通过 bootstrap 的 resolve 属性 将值传递给模态控制器 modal.open方法。我通常会传入多个值,所以我将它们全部放在一个 'options' 复合参数中。

  4. 模态控制器在注入模态控制器时接收此值(在选项中)[解析 属性 在模态控制器请求时提供它]。

  5. 模态控制器然后可以将此值设置到模态视图中(通过模态 $scope/vm)。通常,我在模态对话框中加载数据,例如显示供用户选择的项目列表。

  6. Close event/action 上,我 return 调用者的值(是否被用户交互改变)[是指令的控制器],它将其设置回指令的 [isolated] 作用域,这实际上更新了 mainController 上的 属性,因为它是通过 = 值绑定的。

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