Внедрете персонализирано съобщение за зареждане DURANDAL

Здравейте, имам приложение Durandal, което изпраща данни чрез ajax, но не знам как да внедря индикатора за зареждане, ето кодовете:

това е изгледът, който зарежда данните loadinbox.html

<div class="modal-content messageBox">
    <div class="modal-header">
        <h3>LOGIN</h3>
    </div>
    <div class="modal-body">
       <h3>Entre com suas credenciais.</h3>
       <form data-bind="submit: ok">
           <input type="text" data-bind="value: login" placeholder="CPF"  class="form-control autofocus" />
           <input type="text" data-bind="value: senha" placeholder="Senha" class="form-control autofocus" />
       </form>
    </div>
    <div data-bind="if: $parent.loading">
        <img src="img/loading.gif"/>
    </div>

    <div class="modal-footer">
        <button class="btn btn-success" data-bind="click: ok, active: $parent.loading">Login</button>
    </div>
</div>

това е моделът, който зарежда данните loginBox.js

define(function (require) {
    var dialog = require('plugins/dialog');


    var loading = ko.observable();

    var loginBox = function(){
        this.login = '';
        this.senha = '';
        this.loading = false;
    };


 loginBox.prototype.ok = function () {
     this.loading =true;

     $.ajax({
         type: "post", 
         data: { "LoginForm[cpf]" : this.login, "LoginForm[password]" : this.senha , 'ajax':'login-form' },
         url: localStorage['baseurl']+localStorage['router']+'site/login',
         success: function (data){
             console.log(data);
         },
         error: function (request, status, error){
             console.log(request.status);
             console.log(status);
             console.log(error);
         },
         complete: function (data) {
             alert('hqweuiqhioehqio');
             this.loading =false; 
         }
     });
 };


 loginBox.show = function() {
     return dialog.show(new loginBox());
 };    

 return loginBox;

});

person talles_jp    schedule 28.11.2014    source източник


Отговори (2)


На пръв поглед подходът ви е стабилен, но подходът ви към модулите в Durandal е малко объркан. Например, вие сте декларирали loading два пъти, веднъж като скалар и веднъж като наблюдаем.

И така, нека създадем модул за екземпляр (което означава, че ще върнем конструкторска функция):

loginBox.html (изглед)

<div class="modal-content messageBox">
    <div class="modal-header">
        <h3>LOGIN</h3>
    </div>
    <div class="modal-body">
        <h3>Entre com suas credenciais.</h3>
        <form data-bind="submit: ok">
           <input type="text" data-bind="value: login" placeholder="CPF"  class="form-control autofocus" />
           <input type="text" data-bind="value: senha" placeholder="Senha" class="form-control autofocus" />
        </form>
    </div>
    <div data-bind="if: $parent.loading()">
        <img src="img/loading.gif"/>
    </div>

    <div class="modal-footer">
        <button class="btn btn-success" data-bind="click: ok, active: $parent.loading()">
            Login
        </button>
    </div>
</div>

Забележете, че промених вашето if свързване на това:

"if: loading()"

препращане към loading със скоби. Това извършва незабавно оценяване, като се използва стойността по подразбиране, предоставена на наблюдаемото, и след това повторно оценяване, когато наблюдаемото се промени.

Освен това може да се наложи да промените "click: ok, active: $parent.loading()" на click: $parent.ok.bind($parent), active: $parent.loading(). Проверете контекста си с помощта на дебъгера, когато е въведена функцията #ok.

Бележка относно логиката: Струва ми се, че това, което може да имате предвид в модалния долен колонтитул, е

active: !$parent.loading()

Трябва ли наистина бутонът OK да е активен, когато формулярът зарежда данни?

loginBox.js (подход на екземпляр на модул)

define (
    [
        'plugins/dialog',
        'knockout'
    ],
    function (
        dialog,
        ko) {

        var LoginBox = function () {

            this.login = '';
            this.senha = '';
            this.loading = ko.observable(false);
        };

        LoginBox.prototype.ok = function () {
            var _vm = this;

            this.loading(true);

            $.ajax( {
                type: "post", 
                data: { "LoginForm[cpf]" : this.login, "LoginForm[password]" : this.senha , 'ajax':'login-form' },
                url: localStorage['baseurl']+localStorage['router']+'site/login',
                success: function (data) {
                    console.log(data);
                },
                error: function (request, status, error) {
                    console.log(request.status);
                    console.log(status);
                    console.log(error);
                },
                complete: function (data) {
                    alert('hqweuiqhioehqio');
                    _vm.loading(false);
                }
           });
        };

        LoginBox.prototype.show = function() {
            dialog.show(this);
        };  

        return LoginBox;

    };
);

Обърнете внимание на отношението ми към this.loading. Това е наблюдаема величина и наблюдаемите се актуализират с помощта на подхода, който показвам по-горе (не забравяйте, че те са функции). Когато присвоите true по този начин--this.loading = true--заменяте самото наблюдаемо и го превръщате в ненаблюдаем скалар. Така че, когато стойността по-късно се промени (от false на true на false), изгледът не се актуализира.

Също така имайте предвид, че трябва да импортирате KnockoutJS.

Друг проблем: имате this референтен проблем във вашата функция #complete. Имайте предвид, че правя това в горната част на вашата функция #Ok:

var _vm = this;  //Some people are inclined to this format: var that = this;

и след това във вашата функция #complete правя това:

_vm.loading(false);

Използването на this във вашата функция #complete препраща към самата функция #complete, а не към viewModel. Трябва да запазим препратка към this извън функцията #complete.

Имаше друг проблем: #show не беше на прототипа.

person Community    schedule 28.11.2014
comment
когато отворя сега, той показва изображението за зареждане веднага щом отвори диалоговия прозорец. - person talles_jp; 29.11.2014
comment
@talles_jp Моля, публикувайте целия си изглед (HTML) и viewModel (js). Това, което казвате, ми казва, че по някакъв начин инициализирате loading observable на true или че не сте коригирали изгледа си, за да дереферирате loading observable. Имам нужда от повече информация. - person ; 29.11.2014

Използвам помощна програма, наречена Block UI в моя App JS файл. Наричам я така, като използвам глобалната настройка на Ajax . Правейки го по този начин, вие го правите само веднъж и след това всяко обаждане на Ajax ще показва вашия зареждащ се gif и ще се скрие, когато всяко Ajax повикване започне и завърши

HTML: в страницата index.html (главната ви страница)

  <div id="throbber" style="display:none;">
            <img src="/images/gears.gif" />
        </div>

Javascript

$(document).ready(function () {    
        $.blockUI.defaults.css.border = 'none';
        $.blockUI.defaults.css.backgroundColor = 'transparent';
        $.blockUI.defaults.message = $('#throbber');
        $.blockUI.defaults.showOverlay = true;
        $.blockUI.defaults.overlayCSS.backgroundColor = "#fff";

        $(document).ajaxStart(function () {
                $.blockUI();            
        }).ajaxStop(function () {
            $.unblockUI();
        });
    });

CSS:

#throbber{
    border:1px solid #346789;
    padding: 15px;
    background-Color: #fff;
    -moz-border-radius:0.5em;
    border-radius:0.7em;
    opacity:0.8;
    filter:alpha(opacity=80);
    color: #000 ;
    width:133px;
    height:133px;
    left: 50%;
    top: 40%;
    position: fixed;
 }
person DerfB    schedule 23.02.2015
comment
Използвах и Block UI. Това е добра малка микрорамка. Но ако погледнете въпроса на OP, ще видите, че той използва Durandal. Ние не кодираме директно срещу $(document).ready() в Durandal. Вашият код всъщност би бил най-добър в манипулатора attached на shell.js viewModel. Вие наистина ли правите този Дюрандал? - person ; 24.02.2015