angularjs Angular JS -从异步操作返回结果

qojgxg4l  于 2023-09-30  发布在  Angular
关注(0)|答案(3)|浏览(120)

Angular JS - 1.6.9
我已经在这方面工作了几个小时,坦白地说,我对Angular JS并不熟悉,希望能得到一些指导。
我有一个元素,每次在表单中的字段中更新信息时,它将使用来自这些字段的信息更新“预览窗格”,阅读模板文件,并替换值,打印该信息到预览窗格。(注意:现在我正在阅读每一个字段以任何方式更新,我知道这是不好的,稍后在我得到THIS工作后,我将工作缓存。所以,我不在这一部分寻求帮助,因为我知道我必须解决这个问题,以后会。)
我已经尝试了很多方法,这是最近的尝试,经过几个小时的摆弄,我只是不断得到undefined作为结果到我的控制台。
我非常确信这真的是因为我对异步事物的绝对误解。
我在fillTemplate()中有调试信息,它确实成功地读取了文件,只是,它没有进入浏览器。
超文本标记语言:

<div class="col text-monospace small shadow p-2 mb-2 pre-scrollable">
    {{updateItemInformation()}}
</div>
var app = angular.module('app', ['ngSanitize']);
app.controller('c', ($scope, $sce) => {
    $scope.updateItemInformation = async () => {
        let result ;

        const maxLineLength = 80;

        result = await fillTemplate($scope.item) ;

        console.log(result) ;

        return result ;
    };

    async function fillTemplate(item) {
        let result = "";

        const response = await fetch(`./templates/${item.category}.template`)
        const template = await response.text()

        if(!template) return "";

        return template ;
    }
dvtswwa3

dvtswwa31#

问题似乎是AngularJS无法识别异步函数所做的更新。你需要在异步操作后使用$scope.$apply()手动触发Angular的digest cycle
下面是一个更精简的代码版本:

var app = angular.module('app', ['ngSanitize']);
app.controller('c', ($scope) => {
    $scope.updateItemInformation = async () => {
        const result = await fillTemplate($scope.item);
        console.log(result);
        $scope.$apply(() => {
            $scope.template = result;
        });
    };

    async function fillTemplate(item) {
        const response = await fetch(`./templates/${item.category}.template`);
        return response.text();
    }
});

在HTML中:

<div class="col text-monospace small shadow p-2 mb-2 pre-scrollable">
    {{template}}
    <button ng-click="updateItemInformation()">Refresh Preview</button>
</div>

添加了一个按钮来触发更新并在{{template}}中显示结果。希望这对你有帮助!继续走;你的方向是对的!👍

9avjhtql

9avjhtql2#

AngularJS本身并不支持使用现代JavaScript框架中常用的async/await语法进行异步编程。使用$q服务为XMLHttpRequest构建promise和$http
下面的例子只是一个关于以AngularJS方式构建promise(异步调用)的一般参考。这不是一个字面上的解决方案。

var app = angular.module('app', ['ngSanitize']);
app.controller('c', ($scope, $sce, $http, $log) => {
  $ctrl.$onInit = () => {
    $scope.template = '';
    $scope.updateItemInformation = updateItemInformation;
  }

  function updateItemInformation() {
    fillTemplate($scope.item)
      .then(response => {
        $scope.template = response;
      })
      .catch(error => {
         $log.error(error)
      });
  }

  function fillTemplate(item) {
    const _deferred = $q.defer();
    $http.get(`./templates/${item.category}.template`)
      .then(response => {
        if (!response) _deferred.reject('Template not found');
        _deferred.resolve(response)
      })
      .catch(error => {
        _deferred.reject(error)
      })
    return _deferred.promise;
  }
}
ruarlubt

ruarlubt3#

你的问题是由于AngularJS没有自动重新消化原生async/await的视图。要解决这个问题,请使用范围变量保存结果,并手动监视更改以更新视图。

HTML

<div class="col text-monospace small shadow p-2 mb-2 pre-scrollable">
    {{ previewContent }}
</div>

JS

var app = angular.module('app', ['ngSanitize']);
app.controller('c', function($scope) {

    $scope.previewContent = '';

    $scope.$watch('item', function() {
        updateItemInformation();
    });

    async function updateItemInformation() {
        $scope.previewContent = await fillTemplate($scope.item);
        $scope.$applyAsync(); // Ensure view updates
    }

    async function fillTemplate(item) {
        const response = await fetch(`./templates/${item.category}.template`);
        return response.text();
    }
});

使用$watch检测$scope.item上的更改。当它发生变化时,updateItemInformation被调用,更新$scope.previewContent,然后$applyAsync视图反映变化。

相关问题