Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS视图未更新,而模型在单击输入字段一段时间后发生更改_Javascript_Angularjs_Svg_Angularjs Directive_Ngdraggable - Fatal编程技术网

Javascript AngularJS视图未更新,而模型在单击输入字段一段时间后发生更改

Javascript AngularJS视图未更新,而模型在单击输入字段一段时间后发生更改,javascript,angularjs,svg,angularjs-directive,ngdraggable,Javascript,Angularjs,Svg,Angularjs Directive,Ngdraggable,我制作了一个用于生成PDF的json文件设计器 如果您想看到整个代码的运行,请打开底部的plunker链接 视图的行为与预期不符。在调试器中,当我在SVG场景中拖动元素时,模型会立即更改。 但是输入没有改变。 但是,如果我在输入框之间单击,它会突然将视图更新为正确的值 这是我在指令中设置scope变量值的地方: function endDrag(evt) { if (selectedElement) { let selectedEntry = sc

我制作了一个用于生成PDF的json文件设计器

如果您想看到整个代码的运行,请打开底部的plunker链接

视图的行为与预期不符。在调试器中,当我在SVG场景中拖动元素时,模型会立即更改。 但是输入没有改变。 但是,如果我在输入框之间单击,它会突然将视图更新为正确的值

这是我在指令中设置scope变量值的地方:

    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.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
    }
}
这些是更新太晚的输入字段:

                    <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>

(X,Y)
这是预览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">

它在稍后更新输入字段的事实清楚地表明,数据已正确地传输到控制器。为什么右边的表单更新得这么慢。 难道他们没有办法强迫视图重播吗

提前非常感谢您提供的每一个有用的建议:/


您可以强制视图使用
$scope.$apply()

$apply()用于从AngularJS框架外部执行AngularJS中的表达式。(例如,来自浏览器DOM事件、setTimeout、XHR或第三方库)。因为我们正在调用AngularJS框架,所以我们需要执行异常处理、执行监视的适当范围生命周期

$rootScope.Scope#$apply

还有一个
$applyAsyc()
方法:

将$apply的调用安排在以后进行。实际时差因浏览器而异,但通常约为10毫秒。 这可用于将需要在同一摘要中计算的多个表达式排队

$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();
    }

这样做的原因是,您的拖动事件似乎与Angular的摘要周期没有关联,因此您需要手动调用它,Angular才能对更改进行操作。

我仍然不熟悉$scope。$apply和$digest,但您的示例让它更清楚。感谢您基本上,您在网格中单击的事件处理程序发生在Angular的知识范围之外,因此您需要手动调用scope.$apply(),以便它使用最新更新重新呈现模型。此外,这也是为什么(之前)当您单击输入框时它会更新,因为此时您正在触发角度更新,并且它会跟上对模型所做的更改。当您在角度范围内执行某些操作时,例如使用ng模型,这会自动发生。