使用 http 承诺的 Angularjs 自定义指令不与模板绑定 [英] Angularjs custom directive using http promise not binding with template

查看:20
本文介绍了使用 http 承诺的 Angularjs 自定义指令不与模板绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 angularjs 的新手,想在现有代码中添加新功能.但是代码没有按预期工作.我知道我没有以正确的方式做这件事.请纠正我错误在哪里.我不知道为什么不使用控制器,但在这种方法中使用指令?

这是我的自定义服务和自定义指令指令代码.

服务代码:

angular.module("quickquiz-builder").service("SettingsService", function ($http, $q) {返回 {/* 返回延迟的承诺响应 */得到:函数(){var deferred = $q.defer();$http.get('get.php').then(功能(响应){var config = response.data.config;config = JSON.parse(config);this.generalSettings = config.settings;deferred.resolve(this);}).catch(函数(响应){deferred.reject(response);});返回 deferred.promise;}}})

自定义指令:

angular.module("quickquiz-builder").directive("quizbuilderSettings", ["SettingsService", "QuestionsService", "$filter", function (SettingsService, QuestionsService, c) {返回 {限制:E",范围: {},templateUrl: "templates/settings.html",控制器为:ctrl",控制器:[$scope",函数(作用域){SettingsService.get().then(function (data){/* 在回调中从服务获得响应 */this.settingsService = 数据;scope.settingsService = this.settingsService;this.questionsService = QuestionsService;控制台日志(1);console.log(scope.settingsService.generalSettings);console.log(1+'end');}).catch(函数(e){控制台.dir(e);});}]}}])

在指令中的回调中成功检索到服务响应.但此响应与视图无关.

一段模板代码是:

<md-switch class="md-primary var-label" aria-label="graded" ng-model="ctrl.settingsService.generalSettings.graded" ng-change="ctrl.onChangeGraded()"><strong>分级</strong></md-switch><p flex=""><span ng-if="ctrl.settingsService.generalSettings.graded">测验至少有一个评分问题(一个有正确/错误答案的问题).</span><span ng-if="!ctrl.settingsService.generalSettings.graded">这不是评分测验.</span></p>

解决方案

@doublesharp,你说得对.问题在于数据绑定和范围.

  1. 首先我们需要在 App 指令中正确绑定数据,以便它在视图中可用.

    scope.settingsService = this.settingsService;

我做的已经对了.因为简单地使用'this'操作符,它的作用域就在promise回调函数内.this"运算符不代表控制器/指令级别.

  1. 在视图中正确访问值.

使用

代替

使用ctrl(即controllerAs)访问视图内部的变量/对象不符合指令的范围.因为指令级别的绑定不是使用this"运算符.

I am new to angularjs and want to add new feature in existing code. But code is not working as expected. I know i am not doing it the right way. Please correct me where is the mistake. I don't know why controller is not used but directive is used in this approach?

Here is my custom service and custom directive directive code.

Service code:

angular.module("quickquiz-builder").service("SettingsService", function ($http, $q) {
    return {
    /* Return deffered promise response */
        get: function() {
            var deferred = $q.defer();
            $http.get('get.php')
            .then(function(response){
                var config = response.data.config;
                config = JSON.parse(config);
                this.generalSettings = config.settings;
                deferred.resolve(this);
            })
            .catch(function(response){
              deferred.reject(response);
            });
            return deferred.promise;
        }
    }
})

Custom Directive:

angular.module("quickquiz-builder").directive("quizbuilderSettings", ["SettingsService", "QuestionsService", "$filter", function (SettingsService, QuestionsService, c) {
    return {
        restrict: "E",
        scope: {},
        templateUrl: "templates/settings.html",
        controllerAs: "ctrl",
        controller: ["$scope", function (scope) {
            SettingsService.get().then(function (data){
    /* get response from service inside callback */
                this.settingsService = data;
                scope.settingsService = this.settingsService;
                this.questionsService = QuestionsService;
                console.log(1);
                console.log(scope.settingsService.generalSettings);
                console.log(1+' end');
            }).catch(function(e){
                console.dir(e);
            });
        }]
    }
}])

The service response is retrieved successfully inside callback in directive. But this response is not binding with view.

A piece of template code is:

<div layout="row" class="option">
    <md-switch class="md-primary var-label" aria-label="graded" ng-model="ctrl.settingsService.generalSettings.graded" ng-change="ctrl.onChangeGraded()">
         <strong>Graded</strong>
    </md-switch>
    <p flex=""><span ng-if="ctrl.settingsService.generalSettings.graded">The quiz has at least one graded question (a question that has a right/wrong answer).</span><span ng-if="!ctrl.settingsService.generalSettings.graded">It's not a graded quiz.</span>
    </p>
</div>

解决方案

@doublesharp, you are absolutely right. The problem was with data binding and scoping.

  1. First we need to bind the data properly inside App directive, so it is available in the view.

    scope.settingsService = this.settingsService;

Which I was doing already right. Because simply with 'this' operator, its scope was inside the promise callback function. 'this' operator was not representing for controller/directive level.

  1. Access the value properly in view.

Use

<element nm-model="settingsService.generalSettings.graded"></element>

Instead of

<element nm-model="ctrl.settingsService.generalSettings.graded"></element>

Accessing the variable/object inside view with ctrl (i.e controllerAs) was not according to scope of directive. Because binding at directive level was not with 'this' operator.

这篇关于使用 http 承诺的 Angularjs 自定义指令不与模板绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆