【发布时间】:2014-01-15 10:34:03
【问题描述】:
我一直在尝试创建一个指令,我可以将它任意添加到现有表单(作为属性)中,这会使表单在单击附近的触发链接时成为弹出框。我已经让指令工作了一次,但是一旦我再次单击链接,基础数据不会改变并且按钮(例如“关闭”)停止工作。
可以在这里找到一个 plunker:http://plnkr.co/edit/2Zyg1bLearELpofeoj2T?p=preview
重现步骤: 1. 单击链接,2. 更改文本(注意链接文本也会更改),3. 单击关闭(确定当前没有做正确的事情),4. 再次单击链接, 5. 尝试更改文字/点击关闭,但没有任何效果...
我读到一个问题是引导程序中的弹出框被分离/附加到 DOM,但我不知道如何解决这个问题。我还想避免使用第三方库(例如 angular-ui),因为我想避免开销。
非常感谢任何帮助。
更新
多亏了瓦萨卡的提示,我才得以进步一点。问题略有改变,现在嵌套指令似乎没有从$compile 中受益,即我不相信它附加到范围。
要重现该行为,请单击日期(下面的 plunker 链接),单击弹出窗口中的日期(日期应递增)并关闭弹出窗口。再次重复这些步骤,您会注意到增加日期不再起作用。我尝试添加$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>
【问题讨论】:
-
angular-ui 已经有一个popover了,看看那个,我不知道你说的overhead是什么意思,但是这些组件是原生用angular编写的。
-
我想避免一个额外的库(angular-ui),我称之为开销。
-
您可能想查看this popover 实现。这里的关键是通过覆盖原生引导函数,根据 popover 的显示范围编译 popover 的内容。
-
@Vasaka 谢谢,我会看看他们的实现。
标签: javascript jquery angularjs twitter-bootstrap angularjs-directive