gpt4 book ai didi

angularjs - 在页面焦点之前, Controller 中设置的表单值不会更新

转载 作者:行者123 更新时间:2023-12-01 12:23:16 25 4
gpt4 key购买 nike

这是我的表格的一部分:

<form name="form.activityForm" class="form-horizontal" ng-submit="save(form.activityForm.$valid)"
enctype="multipart/form-data" novalidate>
<fieldset>
<div class="form-group" ng-if="!activity._id">
<label for="gpxData" ng-class="{ 'disabled': gpxFileName }" class="btn btn-primary btn-file">Upload GPX
<input type="file" nv-file-select name="gpxData" id="gpxData" ng-model="gpxData" uploader="uploader"
onchange="angular.element(this).scope().setFileName()" hidden>
</label>
<span ng-if="gpxFileName" ng-bind="gpxFileName"></span>
</div>

<div class="form-group" show-errors>
<label class="control-label" for="name">Name</label>
<input name="name" type="text" ng-model="activity.name" id="name" class="form-control"
ng-disabled="!gpxFileName" required>
<div role="alert" class="alert alert-danger" ng-if="(activity.name === 'N/A') && (gpxFileName)">
<p>This activity does not have a <strong>name</strong>. Please select one.</p>
</div>
<div ng-messages="form.activityForm.name.$error" role="alert">
<p class="help-block error-text" ng-message="required">Activity name is required.</p>
</div>
</div>

...
</fieldset>
</form>

setFileName()

$scope.setFileName = () => {
let fr = new FileReader(),
gpxFile = document.getElementById("gpxData").files[0],
filename = gpxFile.name;

fr.onload = () => {
let gpxDataXml = parseXmlFromString(fr.result);

setNameTypeDescription(gpxDataXml.documentElement);
};
fr.readAsText(gpxFile);
$scope.gpxFileName = filename;
};

setNameTypeDescription()

let setNameTypeDescription = (gpxDataXmlDocumentElement) => {
let activityType = getSingleTagData(gpxDataXmlDocumentElement, "type");

$scope.activity.name = getSingleTagData(gpxDataXmlDocumentElement, "name");
$scope.activity.description = getSingleTagData(gpxDataXmlDocumentElement, "descr");

$scope.activityTypes.forEach((type) => {
if (type.name.toLowerCase() === activityType.toLowerCase()) {
$scope.activity.type = type;
}
});
};

当我在 Controller 中更改值(即 $scope.activity.name)注销时,我得到了预期的输出。但是,模板中的值(即 ng-model="activity.name")不会更新,直到页面上再次出现焦点(即单击按钮)

编辑:

要添加,我需要使用 ng-model,因为我需要 2 种方式绑定(bind)。即使该值最初是在 Controller 中设置的,用户也可以更改模板中的值,并且在提交表单时,该值会保存到 mongo 中。

此外,ng-bind 在这种情况下不起作用。

最佳答案

您的问题是您正在更新绑定(bind)到 View 的值,但 Angular 并不“知道”它们是更新。 Angular 在每个摘要周期更新 View ,这会发生很多次 - 当用户与 View 交互时,或者在 Angular 能够跟踪的范围发生任何更改之后。

在您的情况下,您在文件更改后调用 setNameTypeDescription(在文件输入上使用 onchange 事件。因为 onchange 不是 native angular 指令,您必须手动让 angular 知道某些内容已更改。

当再次聚焦在页面上时它起作用了,因为它触发了更新 View 的摘要循环,但您可以像这样从 Controller 中执行此操作:

$timeout(function() { 
$scope.activity.name = getSingleTagData(gpxDataXmlDocumentElement, "name");

// You can also put here other view related changes, you don't need a separate $timeout for every change
});

当然 - 不要忘记将 $timeout 注入(inject) Controller !

请注意,您还可以使用 $scope.$apply(function() { ... }); 包装代码,但是 $timeout 已经这样做了你,我更喜欢 $timeout,因为在调用 $scope.$apply() 时你不会得到类似 $digest already in progress 的错误,如 this question 中所述。 .

关于angularjs - 在页面焦点之前, Controller 中设置的表单值不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42066225/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com