我正在开发一个简单的HTML编辑器。主要想法是为布局设置"默认主题"和组件可以覆盖主题的值。为了管理主题和组件的样式,我创建了简单的隔离指令,它接受对象和索引。主要问题是,当组件没有样式时,输入标记是空的并且是逻辑上的。有没有办法做不同的事情?
例如,如果组件没有样式,那么在内部指令中它将显示主题的值,但在更改时它将修改组件的样式,而不是主题的。
如果这种架构不是一种有角度的方式,那么你可以建议其他方法吗?
谢谢。
Plunker
这是代码片段:
<!DOCTYPE html>
<html>
<head>
<title>Theme</title>
</head>
<body>
<div data-ng-app="myApp" data-ng-controller="defaultCtrl" style="margin: 100px 100px">
<ol>
<li data-ng-repeat="component in document" data-ng-style="m(theme, component.style)" data-ng-controller="componentController" data-ng-init="init(component)">
{{ theme }}
{{ component }}
{{ component.content }}
<button data-ng-click="editComponent()">Edit component</button>
</li>
</ol>
<button data-ng-click="editTheme()">Edit theme</button>
<div id="editor"></div>
<script type="text/ng-template" id="component.html">
<p>Component</p>
<border-editor ref-obj="component.style" ref-index="border"></border-editor>
</script>
<script type="text/ng-template" id="theme.html">
<p>Theme</p>
<border-editor ref-obj="theme" ref-index="border"></border-editor>
</script>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("defaultCtrl", ["$scope", "$templateCache", "$compile", function($scope, $templateCache, $compile) {
$scope.theme = {
border: "1px solid red"
}
$scope.document = [
{
content: "First block",
style: {
border: "1px solid green"
}
},
{
content: "Second Block",
style: {}
},
{
content: "Third block",
style: {}
}
];
$scope.m = function() {
var merged = {},
args = arguments.length;
for (var i = 0; i < args; i++) {
for (var k in arguments[i]) {
if (arguments[i].hasOwnProperty(k) && arguments[i][k] !== undefined) {
merged[k] = arguments[i][k]
}
}
}
return merged;
}
$scope.editTheme = function() {
$scope.createEditor($scope, 'theme.html');
}
var editorScope;
function createEditor(scope, tpl) {
if(editorScope) {
editorScope.$destroy();
}
var tpl = $templateCache.get(tpl);
editorScope = scope.$new();
var content = $compile(tpl)(editorScope);
$("#editor").html(content);
}
$scope.createEditor = createEditor;
}]);
app.controller("componentController", ["$scope", function($scope) {
$scope.init = function(component) { $scope.component = component; }
$scope.editComponent = function() {
$scope.createEditor($scope, 'component.html');
}
}]);
app.directive("borderEditor", function() {
return {
restrict: "E",
scope: {
refObj: "=",
refIndex: "@"
},
template: '<input data-ng-model="refObj[refIndex]" />',
link: function(scope, el, a) {}
}
})
</script>
</body>
</html>
答案 0 :(得分:0)
行。我找到了解决方案。我将 ng-model 与 $ parsers 和 $ formatters 属性结合使用。
我建议每个不了解ng模型如何运作的人 - read this article。
这是updated plunker。
app.directive("borderEditor", function() {
return {
restrict: "E",
scope: {
ngModel: "=",
alternate: "="
},
require: "^ngModel",
template: '{{ngModel || "undefined" }} <input data-ng-model="border"/>',
link: function(scope, el, a, ngModel) {
ngModel.$formatters.push(function(modelValue) {
return !modelValue ? scope.alternate : modelValue;
});
ngModel.$parsers.push(function(viewValue) {
return viewValue;
});
ngModel.$render = function() {
scope.border = ngModel.$viewValue;
}
scope.$watch("border", function(newValue, oldValue) {
if(newValue != oldValue) {
ngModel.$setViewValue(newValue);
}
});
}
}
})