s.a*_*lem 7 javascript forms angularjs angularjs-directive
我想听一个指令中的表单提交.说我有这样的指令:
app.directive('myDirective', function () {
return {
restrict: 'A',
require: '^form',
scope: {
smth: '='
},
link: function (scope, el, attrs, formCtrl) {
scope.$watch(function(){
return formCtrl.$submitted;
},function(currentValue){
console.log('submitted');
});
}
}
});
Run Code Online (Sandbox Code Playgroud)
通过上面的方法,我可以看到第一次提交,但不是其余的.我试着这样做:
scope.$watch(function () {
return formCtrl.$submitted;
}, function (currentValue) {
if (currentValue) {
console.log('submitted');
formCtrl.$setPristine(); // Watch this line!
}
});
Run Code Online (Sandbox Code Playgroud)
但问题是,如果我多次使用表单中的指令,它只适用于第一次使用.我想知道的是,是否有类似formCtrl.onsubmit(...)或任何解决方法来获得相同的功能.在此先感谢任何帮助......
rye*_*lar 15
而是看的$submitted属性,您可以创建具有相同的名称作为一个指令form其连接与形式的事件处理程序提交广播,你可以在你听角事件指令myDirective指令.您不必担心覆盖form指令的角度实现,它只会附加您的行为而不会覆盖内置实现.
注意:您也可以选择不向form指令附加功能,而是选择另一个指令名称,只需确保将该指令名称作为表单标记中的属性附加以触发事件.
使用Javascript
.directive('form', function() {
return {
restrict: 'E',
link: function(scope, elem) {
elem.on('submit', function() {
scope.$broadcast('form:submit');
});
}
};
})
.directive('myDirective', function() {
return {
require: '^form',
link: function(scope, elem, attr, form) {
scope.$on('form:submit', function() {
form.$setPristine();
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
鉴于以下评论中提出的问题:
什么是检查是否有"我的指示性"属性的元素有"我型"的最有效的方式(如果我的名字"形式"指令"myForm会")属性,它的父窗体?所以我可以使用"myDirective",有或没有"myForm"(当然也有相应的行为)
有几种方法可以做到:
.data()在你的方法myForm指令在编译阶段,并访问它的链接功能时,您在myDirective使用该.inheritedData()方法,如果在指定的数据form存在指令.请注意,我form在myForm指令中的广播中传递了控制器.这可确保您收到来自form元素的父表单控制器.有一定的使用情况,其中,你可以使用myDirective经由嵌套形式内ng-form,因此,而不是设置form.$setPristine()于form元件形式控制器你会设置ngForm形式的控制器.
.directive('myForm', function() {
return {
require: 'form',
compile: function(tElem, tAttr) {
tElem.data('augmented', true);
return function(scope, elem, attr, form) {
elem.on('submit', function() {
scope.$broadcast('form:submit', form);
});
}
}
};
})
.directive('myDirective', function() {
return {
link: function(scope, elem, attr) {
if(!elem.inheritedData('augmented')) {
return;
}
scope.$on('form:submit', function(event, form) {
console.log('submit');
form.$setPristine();
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
myForm指令中创建一个控制器,用于存储表单事件处理程序,以便在触发表单事件时进行迭代.而不是使用$broadcast实际比下面的实现慢的角度事件,因为它遍历从form元素到最后一个范围链的每个范围.myForm下面的控制器创建自己的机制来存储事件处理程序.正如在#1中实现的那样,当深埋并嵌套来自许多元素时,使用.data()- inheritedData()是很慢的myDirective,因为它遍历DOM向上直到找到特定的元素data.使用下面的实现,您可以检查?^myForm父级中是否存在所需的控制器,请注意?它代表可选的要求.此外,在myForm指令中将scope设置为true 允许您使指令可重用,例如myForm在页面内有多个指令. .directive('myForm', function() {
return {
require: ['form', 'myForm'],
scope: true,
controller: function() {
this.eventHandlers = {
submit: [],
change: []
};
this.on = function(event, handler) {
if(this.eventHandlers[event]) {
this.eventHandlers[event].push(handler);
}
};
},
link: function(scope, elem, attr, ctrls) {
var form = ctrls[0],
myForm = ctrls[1];
angular.forEach(myForm.eventHandlers, function(handlers, event) {
elem.on(event, function(eventObject) {
angular.forEach(handlers, function(handler) {
handler(eventObject, form);
});
});
});
}
};
})
.directive('myDirective', function() {
return {
require: '?^myForm',
link: function(scope, elem, attr, myForm) {
if(!myForm) {
return;
}
myForm.on('submit', function(event, form) {
console.log('submit');
form.$setPristine();
});
}
};
});
Run Code Online (Sandbox Code Playgroud)