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



我将以下HTML从控制器移动到指令中,作为单击按钮时要插入的HTML的一部分。问题是现在保存按钮(下面)什么也不做。我尝试将ng-click更改为指令代码中包含的另一个函数,结果成功了,但我知道保存数据的函数属于控制器。如何访问saveStudent函数?(当HTML在视图中时,我曾在控制器中使用$scope.saveStudent。)

如果以前有人问过这个问题,我很抱歉。我尽了最大的努力来浏览相关的问题,但我是个新手,所以很可能我错过了一个类似的问题。谢谢

<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没有错。

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

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

假设您的指令是您的控制器所在的HTML的子级:

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

你有几个选择。

我假设您的控制器中有一堆冗长的业务逻辑,指令中也有一堆交互处理。。。我还想假设,你希望这个指令可以重复使用(在理想的世界里),或者至少不应该泄露东西,除了你明确允许它接触的东西。

所以,如果你的控制器看起来像这样:

["$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;
});

这个scope属性将产生所有的区别:
在指令对象(JS)中定义它,就像这样…

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

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

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

这给我们带来了什么?

"&"表示父控制器正在为您提供一个函数(或任何表达式,该表达式将封装在隐式函数中),该函数可以在指令内部调用,但将在父控制器的作用域中激发。

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

因此,在指令的实际模板中,您现在可以编写:

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

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

scope : {
propName : "="
}

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

所以如果我假设

// 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方法,而不是编译器。

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

现在是凌晨2点,我希望这有帮助。。。

由于您的文章中可用的代码有限,这是我能做的最好的事情。我希望它能有所帮助!

原始属性将被复制到新元素中,因此引用应该都能工作,即使您为按钮提供了一个独立的范围。

现场演示(点击)

<button    
my-directive=""
ng-click="saveStudent()"
ng-enable="addStudentForm.$valid"
></button>

JavaScript:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.saveStudent = function() {
console.log('saving student!');
};
});
app.directive('myDirective', function() {
return {
replace: true,
template: '<button class="btn-bl btn-bl-red pull-right">SAVE</button>'
};
});

最新更新