我一直在尝试创建一个可以任意添加到现有表单(作为属性)的指令,这使得表单在单击附近的触发链接时成为一个弹出窗口。我已经让指令工作了一次,但是一旦我再次点击链接,基础数据就不会改变,按钮(例如'close')就会停止工作。
可以在这里找到一个plunker:http://plnkr.co/edit/2Zyg1bLearELpofeoj2T?p=preview
重现步骤:1。单击链接,2。更改文本(注意链接文本也会更改),3。单击关闭(确定当前没有正确的操作),4。再次单击链接,5。尝试更改文本/单击关闭,但没有任何作用...
我读过一个问题是bootstrap中的popovers分离/附加到DOM,但我不知道如何解决这个问题。我也想避免第三方库(例如angular-ui),因为我想避免开销。
非常感谢任何帮助。
更新
感谢Vasaka的暗示,我能够进一步发展。问题略有改变,因为嵌套指令现在似乎没有从$compile
中受益,即我不相信它附加到范围。
要重现该行为,请单击日期(下面的plunker链接),单击popover中的日期(日期应递增)并关闭弹出窗口。再次重复这些步骤,您会注意到递增日期不再起作用。我尝试添加$compile(element.contents())(scope)
以尝试编译嵌套指令simple-date-picker
,但这并没有解决问题。
这是更新的plunker:http://plnkr.co/edit/2Zyg1bLearELpofeoj2T?p=preview
更新的代码:
<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css@*" data-semver="3.0.3" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
<script data-require="jquery@1.9.1" data-semver="1.9.1" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script data-require="bootstrap@2.3.2" data-semver="2.3.2" src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script data-require="angular.js@1.2.5" data-semver="1.2.5" src="http://code.angularjs.org/1.2.5/angular.js"></script>
<style>
body {margin-top:40px; margin-left:40px;}
</style>
<script>
var module = angular.module('module', []);
module.directive('simpleDatePicker', function($compile) {
return {
restrict: 'E',
scope: {
date: '='
},
replace: true,
template: '<div ng-click="date.setDate(date.getDate()+5)"> {{ date }} </div>',
}
});
module.directive('myForm', function() {
return {
restrict: 'E',
scope: {
popover: '=?',
value: '='
},
transclude: true,
replace: true,
template:
'<div>' +
'<a href="" ng-transclude></a>' +
'<form ng-submit="submit($event)" ng-hide="popover && !formVisible" ng-attr-popover="{{ popover }}" class="form-inline">' +
'<simple-date-picker date="value"></simple-date-picker>' +
'<div ng-hide="!popover">' +
'<button type="submit" class="btn btn-primary">OK</button>' +
'<button type="button" class="btn" ng-click="formVisible=false">close</button>' +
'</div>' +
'<div class="editable-error help-block" ng-show="error">{{ error }}</div>' +
'</form>' +
'</div>',
controller: function($scope, $element, $attrs) {
$scope.formVisible = false;
$scope.submit = function(evt) {
$scope.formVisible = false;
}
}
}});
module.directive('popover', function($compile) {
return {
restrict: 'A',
scope: false,
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
},
post: function postLink(scope, iElement, iAttrs, controller) {
var attrs = iAttrs;
var element = iElement;
// We assume that the trigger (i.e. the element the popover will be
// positioned at is the previous child.
var trigger = element.prev();
var popup = element;
// Connect scope to popover.
trigger.on('shown', function() {
var tip = trigger.data('popover').tip();
$compile(tip)(scope);
scope.$digest();
});
trigger.popover({
html: true,
content: function() {
scope.$apply(function() {
scope.formVisible = true;
});
return popup;
},
container: 'body'
});
scope.$watch('formVisible', function(formVisible) {
if (!formVisible) {
trigger.popover('hide');
}
});
if (trigger.data('popover')) {
trigger.data('popover').tip().css('width', '500px');
}
}
}
}
};
});
function MyCtrl($scope) {
$scope.value = new Date(0);
}
angular.element(document).ready(function() {
angular.bootstrap(document, ['module']);
});
</script>
</head>
<body ng-controller="MyCtrl">
<my-form popover="true" value="value">
{{ value }}
</my-form>
</body>
</html>
答案 0 :(得分:1)
我想我解决了这两个问题。如果有人感兴趣,我会很快总结我的发现:
1)根据Vasaka的建议,弹出窗口的tip
需要绑定到范围($compile(tip)(scope)
)。
2)第二个问题是嵌套指令不是由(1)中的$compile()
调用编译的。这是因为在replace: true
的(嵌套)指令定义对象中设置了simple-date-picker
。由于原始指令标记最初被替换,因此任何后续的$compile
运行都不会将简单的日期选择器识别为Angular指令。
最终plunker(唯一的区别是replace: false
)。