我将以下 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/