cod*_*.de 2 javascript svg angularjs angularjs-directive ngdraggable
我制作了一个用于生成 PDF 的 json 文件设计器。
如果您想查看整个代码的运行情况,请打开底部的 plunker 链接。
该视图的行为不符合预期。在调试器中,当我在其 SVG 场景中拖动元素时,模型会立即更改。输入不会改变。但是,如果我在输入框之间单击,它会突然将视图更新为正确的值。
这是我在指令内的范围变量中设置值的地方:
function endDrag(evt) {
if (selectedElement) {
let selectedEntry = scope.data.templateData.find(function(entry) {
return entry.name === selectedElement.getAttribute("data-entry-name");
});
if(selectedEntry){
selectedEntry.x = parseInt(selectedElement.transform.baseVal.getItem(0).matrix.e / scope.data.pdfViwer.zoom);
selectedEntry.y = parseInt(selectedElement.transform.baseVal.getItem(0).matrix.f / scope.data.pdfViwer.zoom);
}
selectedElement = null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我在控制器中的数据对象:
$scope.data = {
name: "",
type: [{name:'Text',value:'text'}, {name:'Image',value:'image'}, {name:'Line',value:'line'}],
templateData: [{
'type': {name:'Text',value:'text'},
'name': 'test',
'text': 'test3',
'x': 100,
'y': 100
}],
pdfViwer: {
height: 2970,
width: 2000,
zoom: .3
},
output: {
show:true
}
}
Run Code Online (Sandbox Code Playgroud)
这些是更新太晚的输入字段:
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">(X,Y)</span>
</div>
<input type="text" ng-model="entry.x" aria-label="x" ng-init="entry.x=data.pdfViwer.width / 2" class="form-control">
<input type="text" ng-model="entry.y" aria-label="y" ng-init="entry.y=data.pdfViwer.height / 2" class="form-control">
</div>
Run Code Online (Sandbox Code Playgroud)
这是预览 SVG 中 svg 组的组标签:
<g ng-repeat="entry in getTemplateData()" class="draggable" data-entry-name="{{entry.name}}"
transform="translate({{entry.x * data.pdfViwer.zoom}} {{entry.y * data.pdfViwer.zoom}})"
draggable="true">
Run Code Online (Sandbox Code Playgroud)
它稍后更新输入字段的事实清楚地表明数据已正确传输到控制器。为什么右边的Form更新这么懒。他们没有办法强制视图重新渲染吗?
非常感谢您的每一个有用的建议:/
您可以强制视图渲染 $scope.$apply()
$apply() 用于从 AngularJS 框架之外执行 AngularJS 中的表达式。(例如来自浏览器 DOM 事件、setTimeout、XHR 或第三方库)。因为我们正在调用 AngularJS 框架,所以我们需要执行异常处理、执行监视的适当范围生命周期。
https://docs.angularjs.org/api/ng/type/ $rootScope.Scope#$apply
还有一种$applyAsyc()方法:
安排 $apply 的调用在以后发生。实际时间差异因浏览器而异,但通常约为 10 毫秒。这可用于将需要在同一摘要中计算的多个表达式排队。
https://docs.angularjs.org/api/ng/type/ $rootScope.Scope#$applyAsync
我玩弄了你的 plnker,看起来如果你把它放在函数scope.$apply();的末尾,endDrag()它就会按预期工作:
function endDrag(evt) {
if (selectedElement) {
let selectedEntry = scope.data.templateData.find(function(entry) {
return entry.name === selectedElement.getAttribute("data-entry-name");
});
if(selectedEntry){
selectedEntry.x = parseInt(selectedElement.transform.baseVal.getItem(0).matrix.e / scope.data.pdfViwer.zoom);
selectedEntry.y = parseInt(selectedElement.transform.baseVal.getItem(0).matrix.f / scope.data.pdfViwer.zoom);
}
selectedElement = null;
}
scope.$apply();
}
Run Code Online (Sandbox Code Playgroud)
这样做的原因是看起来好像您的拖动事件与 Angular 的摘要循环无关,因此您需要手动调用它,以便 Angular 对更改采取行动。
| 归档时间: |
|
| 查看次数: |
1609 次 |
| 最近记录: |