zoukankan      html  css  js  c++  java
  • 4.11 Routing -- Loading/Error Substates

    除了在上节中描述的技术,Ember路由器通过使用errorloading substates为自定义异步跳转提供强大而可重写的约定。

    一、loading Substates

    1. 在跳转过程中,Ember路由器允许你从各种各样的beforeModel/model/afterModel hooks中返回promises。这些promises暂停跳转直到它们被执行,此时跳转会恢复。

    2. 考虑下面的例子:

    app/router.js

    Router.map(function() {
      this.route('foo', function() {
        this.route('slow-model');
      });
    });

    app/routes/soo/slow-modal.js

    export default Ember.Route.extend({
      model() {
        return somePromiseThatTakesAWhileToResolve();
      }
    });
    • 如果我们访问foo/slow-model,并且在model hook中,你返回一个需要花很长时间去执行的AJAX查询promise。在这期间,你的用户界面并没有给你反馈真正正在发生什么;
    • 如果你在整个页面刷新后正在进入这个路由,你的用户界面将完全空白,你还没有完全进入任何路由,并且还没有显示任何模板;
    • 如果你从其他路由导航到foo/slow-model,你将会继续看到来自前一个路由的模板知道model完成加载,然后,很快,突然的所有foo/slow-model的模板加载了。

    2. 所以,我们如何在跳转中提供一些视觉返回?

    3. Ember提供了一个loading进程的默认实现,它实现了下面的loading substate行为。

    app/router.js

    Router.map(function() {
      this.route('foo', function() {
        this.route('bar', function() {
          this.route('baz');
        });
      });
    });
    • 如果一个路径为foo.bar.baz的路由返回了一个不会被立即解析的promise,Ember将会尝试在foo.bar.baz的上层寻找一个loading route,它可以跳转进入,用foo.bar.baz的一部分作为开始:
      • foo.bar.loading
      • foo.loading
      • loading
    • Ember将会找到一个loading route在上面的位置,如果
      • 一个路由子类已经被定义为这样一个路由,例如
        • app/routes/foo/bar/loading.js
        • app/routes/foo/loading.js
        • app/routes/loading.js
      • 或者一个被正确命名的loading template已经被找到,例如
        • app/templates/foo/bar/loading.hbs
        • app/templates/foo/loading.hbs
        • app/templates/loading.hbs

    4. 在一个慢的异步跳转过程中,Ember将会跳转到它找到的第一个sub-state/route,如果存在的话。中间跳转到loading substate立刻发生(同步),URL不会被更新,并且不像其他跳转,当另外一个异步跳转是活动的,当前活动的异步跳转不会被终止。

    5. 在跳转到一个loading substate之后,substate对应的template,如果存在,将会被渲染到父路由主要的outlet中,例如,foo.bar.loading的模板将会渲染到foo.baroutlet中。(这对loading routes来说并不特别,这种方式是所有路由的默认行为。)

    6. 一旦主要的异步跳转foo.bar.baz完成了,loading substate将会跳出,它的模板被销毁,foo.bar.baz将会被进入并且它的模板被渲染。

    二、Eager VS. lazy async transitions

    1. Loading substates是可选的,但是如果你提供了一个,你基本上告诉Ember你希望这个异步跳转是"eager";

    2. 在没有目的的路由上loading substates,这个路由将会"lazily"留在之前跳转的路由上,直到所有目标路由的promise被解析,并且一旦跳转完成只有完全的跳转到目标路由。但是,一旦你提供一个目标路由loading substates,你就选择进入了"eager"跳转,这就是说,不像默认的"lazy",你会急切的退出源路由(并且销毁它们的模板),为了跳转到substate。URL总是立即更新除非跳转被终止或者在同一运行循环中重定向。

    3. 这在错误处理上是有意义的,例如,当跳转到另一条路由失败时,一个lazy跳转将(默认的)只停留在上一个路由上,而eager跳转将已经离开了跳转前的路由并且进入了loading substate。

    三、The loading event

    1. 如果你从多样的beforeModel/model/afterModel hooks中返回一个promise,并且它没有立即解析,一个loading事件将会被激活到路由并且冒泡到route:application上。

    2. 如果loading处理器没有被定义到指定的路由,该事件将会继续冒泡到一个跳转的支点路由,提供给route:application机会去管理它。

    app/routes/foo-slow-model.js

    export default Ember.Route.extend({
      model() {
        return somePromiseThatTakesAWhileToResolve();
      },
      actions: {
        loading(transition, originRoute) {
          //displayLoadingSpinner();
          this.router.one('didTransition', function () {
            // hideLoadingSpinner();
          });
    
          // Return true to bubble this event to `FooRoute`
          // or `ApplicationRoute`.
          return true;
        }
      }
    });

    3. 在应用程序加载的过程中loading处理器决定做什么。如果最后的loading handler没有被定义或者返回true,Ember将会实现loading substate行为。

    app/routes/application.js

    export default Ember.Route.extend({
      actions: {
        loading(transition, originRoute) {
          displayLoadingSpinner();
    
          // substate implementation when returning `true`
          return true;
        }
      }
    });

    四、error Substates

    1. Ember在跳转期间遇到错误的情况下提供了一个和loading substates类似的处理。

    2. 和默认的loading事件处理器怎么被实现的一样,默认的error handlers将会寻找进入合适的error substate,如果可以找到一个。

    app/router.js

    Router.map(function() {
      this.route('articles', function() {
        this.route('overview');
      });
    });

    3. 例如,从route:articles/overview#model hook被返回一个抛出的错误或者被拒绝的promise将会查找:

    • route:articles/error或者articles/error模板
    • route:error或者error模板
    • 如果上面中的一个被找到,路由器将会立刻跳转到substate(不更新URL)。错误的原因将会作为它的model被传递到error state。
    • 如果没有可视化的error substates被发现,一个错误信息将被日志记录。

    五、error substates with dynamic segments

    1. 带有动态字段的路由经常会被映射到一个two separate levels" 的mental model。例:

    app/router.js

    Router.map(function() {
      this.route('foo', { path: '/foo/:id' }, function() {
        this.route('baz');
      });
    });

    app/routes/foo.js

    export default Ember.Route.extend({
      model(params) {
        return new Ember.RSVP.Promise(function(resolve, reject) {
           reject("Error");
        });
      }
    });
    • 在URL层上你将会访问/foo/12,这将导致加载foo模板到application模板的outlet
    • 在错误事件中当尝试加载foo路由,你将也会渲染顶层的error模板到application模板的outlet
    • 这是有意的平行的行为,当foo路由从来不会被成功进入时。
    • 为了给错误创建一个foo作用域并且加载foo/errorfoooutlet,你需要拆分动态字段:
    • app/router.js
    • Router.map(function() {
        this.route('foo', {path: '/foo'}, function() {
          this.route('elem', {path: ':id'}, function() {
            this.route('baz');
          });
        });
      });

    六、The error event

    1. 如果oute:articles/overviewmodel hook返回一个被拒绝的promise(例如服务器返回错误,用户没有登录等),一个error event将会被激活到route:articles/overview并且冒泡。这个error event可以被处理并且用来展示一个错误信息,重定向到登录页面。

    例子:

    app/routes/article-overview.js

    export default Ember.Route.extend({
      model(params) {
        return new Ember.RSVP.Promise(function(resolve, reject) {
           reject("Error");
        });
      },
      actions: {
        error(error, transition) {
    
          if (error && error.status === 400) {
            // error substate and parent routes do not handle this error
            return this.transitionTo('modelNotFound');
          }
    
          // Return true to bubble this event to any parent route.
          return true;
        }
      }
    });

    2. 和loading event相似,你可以在应用程序级别管理错误事件执行任何应用程序逻辑,并基于过去的错误处理的结果,Ember将决定是否必须执行substate行为。

    app/routes/application.js

    export default Ember.Route.extend({
      actions: {
        error(error, transition) {
    
          // Manage your errors
          Ember.onerror(error);
    
          // substate implementation when returning `true`
          return true;
    
        }
      }
    });
  • 相关阅读:
    20155305《网络对抗》Web安全基础实践
    20155305《网络对抗》Web基础
    20155305《网络对抗》网络欺诈技术防范
    20155305《网络对抗》信息搜集与漏洞扫描
    20155305《网络对抗》MSF基础应用
    20155305《网络对抗》恶意代码分析
    20155305《网络对抗》免杀原理与实践
    20155305《网络对抗》后门原理与实践
    20155305《网络对抗》PC平台逆向破解(二)
    20155305乔磊《网络对抗》逆向及Bof基础
  • 原文地址:https://www.cnblogs.com/sunshineground/p/5158087.html
Copyright © 2011-2022 走看看