javascript - 如何使用 $scope 从 angularjs 中的指令添加的 HTML 调用函数

标签 javascript html angularjs

我将以下 HTML 从 Controller 移至指令,作为 HTML 的一部分,我希望在单击按钮时插入其中。问题是现在保存按钮(下方)什么都不做。我尝试将 ng-click 更改为我在指令代码中包含的不同功能,并且有效,但我知道保存数据的功能属于 Controller 。如何访问 saveStudent 函数? (当 HTML 位于 View 中时,我过去常常在 Controller 中使用 $scope.saveStudent。)

如果之前有人问过这个问题,我很抱歉。我尽力查看相关问题,但我是 Angular 的新手,所以很可能我错过了一个类似的问题。谢谢!

<button class="btn-bl btn-bl-red pull-right" ng-click="saveStudent(addStudentForm);" ng-enable="addStudentForm.$valid">
    SAVE
</button>

这是在单击按钮时加载新模板的函数(在指令的链接函数中)。

        function studentEditForm(element) {
            var templateUrl = baseUrl + 'settings-edit.html';
            templateLoader = $http.get(templateUrl, {
                cache : $templateCache
            }).success(function(html) {
                element.html(html);
            }).then(function() {
                var compiled = $compile(element.html())(scope);
                element.html(compiled);
            });

        };

        templateLoader.then(function() {
            var compiled = $compile(element.html())(scope);
            element.html(compiled);
        });

我想知道 HTML 是否由指令编译这一事实是否是问题所在?

最佳答案

m59 没有错。

但有时,真正的答案并不那么容易(出于一千种不同的原因)。

有几个选项可以提供帮助。

假设您的指令是您的 Controller 所在的 HTML 的子级:

<div ng-controller="myController">
    <my-save-directive></my-save-directive>
</div>

您有几个选择。

我假设你的 Controller 中有一堆冗长的业务逻辑,你的指令中有一堆交互处理......我也假设你希望这个指令可以重用(在理想的世界中),或者至少不应该泄漏东西进出它,除了你明确允许触摸的东西。

所以如果你的 Controller 看起来像这样:

["$scope", "$http", function ($scope, $http) {

     $scope.doStuff = function () { };
     $scope.students = [];
     $scope.saveStudent = function (particularStudent) {
         $http.post(particularStudent);
     };

}]

那么您的选项可能如下所示:

//mySaveDirective.js
angular.module("...").directive("mySaveDirective", function () {

    var directive = {
        template : "<button ng-click='save(subject)'>SAVE</button>",
        scope : { // <----here's the key bit
            save    : "&",
            subject : "="
        },
        link : function ($scope, el, attrs, ctrl) {
            // .......
        }
    };

    return directive;

});

范围属性将产生重大影响:
像这样在指令对象 (JS) 中定义它...

scope : {
   camelName : "&",
   otherName : "="
}

...并在指令的 HTML 声明中使用它(不是(!!!)实际模板)

<my-save-directive  camel-name="saveStudent(subject)" other-name="student"></my-save-directive>

这给我们带来了什么?

“&”意味着父 Controller 给你一个函数(或任何表达式,将被包裹在一个隐式函数中),它可以在指令内调用,但会在父级的范围内触发。

<div controller="myController">
    <my-directive directive-method-name="controllerFunc(directiveArgName)"></...>

所以在你的指令的实际模板中,你现在可以写:

<button ng-click="directiveMethodName({ directiveArgName : scopeObj })">

它持有具有同名属性的对象的原因是因为 Angular 解析方法定义的方式与它在其他地方解析 DI 的函数定义的方式相同。

scope : {
    propName : "="
}

意味着您可以在该属性上设置父级和指令之间的双向绑定(bind)。
它可以是一个对象或一个值,也可以是来自一端或另一端的方法,或者一个消息系统/事件系统来进行通信。
如果一端更改值,另一端也会更改。

如果我假设

// StudentController
$scope.student = {};
$scope.saveStudent = function (student) { };

那么指令 JS 可以是这样的:

// SaveDirective
var directive = {
    scope : {
        subject : "=",
        save    : "&"
    }
};

以及声明指令的 HTML(未编译):

<div ng-controller="studentController">
    <div save-directive  subject="student" save="saveStudent(subject)">

最后,按钮:

<button ng-click="save({ subject : subject })">SAVE</button>

我希望这是有道理的。

此外,您很少会关心 $compile。
几乎没有,除非您正在编写需要在使用模板之前对模板进行大量修改的内容(此时,为什么不编写不同的模板?)。

通常,在指令中,您比编译器更关心 link 方法。

区别在于编译器在模板上运行一次,句点。
如果你在 8 个不同的地方使用相同的指令,编译器仍然只会运行一次(除非你出于某种原因强制它)。
链接函数针对模板的每个实例(给定的最终克隆节点)运行,您还可以访问指令的范围,并正确链接到位于顶部的所有内容。

...现在是凌晨 2 点,希望对您有所帮助...

关于javascript - 如何使用 $scope 从 angularjs 中的指令添加的 HTML 调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21129928/

相关文章:

javascript - 设置上下文时使用绑定(bind)的替代方法是什么?

javascript - MVC 和 JQuery 日期选择器 - 日期选择器初始化时的错误日期格式

javascript - AngularJS : How to bind data to a Directive?

javascript - 模板不渲染重新加载的数据: AngularJS

javascript - 如何从aspx页面隐藏用户控件div?

javascript - 是否可以将诸如 Geolocation.watchPosition() 之类的函数包装在 Promise 中?

javascript - 在加载时从 html Javascript 生成服务器 cgi?

html - 在不更改 HTML 的情况下为移动和桌面 View 重新安排 flex 元素

javascript - 更新 div 内容时避免浏览器自动滚动

javascript - 变量访问的 Angular 和 javascript 范围