Home  >  Article  >  Web Front-end  >  Comprehensive analysis of Router routing in JavaScript's Backbone.js framework

Comprehensive analysis of Router routing in JavaScript's Backbone.js framework

高洛峰
高洛峰Original
2017-02-06 11:49:251153browse

The Router in Backbone acts as a route and controls the direction of the URL. It takes effect when the # tag is used in the URL.
Defining Router requires at least one Router and a function to map a specific URL, and we need to remember that in Backbone, any characters after the # tag will be received and interpreted by Router.
Let’s define a Router:

<script>
 var AppRouter = Backbone.Router.extend({
  routes: {
   "*actions": "defaultRoute" // 匹配 http://example.com/#anything-here
  }
 });
 // 实例化 Router
 var app_router = new AppRouter;
 
 app_router.on(&#39;route:defaultRoute&#39;, function(actions) {
  alert(actions);
 })
 
 // 打开 Backbone 的历史记录
 Backbone.history.start();
</script>

Now, we have defined a Router, but at this time the Router does not match a specific URL. Next, we will start to explain in detail how the Router works. .

Dynamic routing
Backbone allows you to define Routers with specific parameters. For example, you may want to receive a post with a specific id, such as this URL: "http://example.com/#/posts/12". Once the Router is activated, you can get a post with id 12. post. Next, let’s define this Router:

<script>
 var AppRouter = Backbone.Router.extend({
  routes: {
   "posts/:id": "getPost",
   "*actions": "defaultRoute" //Backbone 会根据顺序匹配路由
  }
 });
 // 实例化 Router
 var app_router = new AppRouter;
 app_router.on(&#39;route:getPost&#39;, function (id) {
  // 注意,参数通过这里进行传递
  alert( "Get post number " + id ); 
 });
 app_router.on(&#39;route:defaultRoute&#39;, function (actions) {
  alert( actions ); 
 });
 // 打开 Backbone 的历史记录
 Backbone.history.start();
</script>

Matching rules
Backbone uses two forms of variables to set the Router’s matching rules. The first is :, which matches any parameter between slashes in the URL, and the other is *, which matches everything after the slashes. Note that since the second form is more fuzzier than the first, it has the lowest matching priority.
The results of any form of matching will be passed to the relevant function in the form of parameters. The first rule may return one or more parameters, and the second rule will return the entire matching result as one parameter.
Next, we use examples to illustrate:

routes:{
 
 "posts/:id": "getPost",
 // <a href="http://example.com/#/posts/121">Example</a>
 
 "download/*path": "downloadFile",
 // <a href="http://example.com/#/download/user/images/hey.gif">Download</a>
 
 ":route/:action": "loadView",
 // <a href="http://example.com/#/dashboard/graph">Load Route/Action View</a>
 
},
 
app_router.on(&#39;route:getPost&#39;, function( id ){ 
 alert(id); // 匹配后,传递过来的参数为 12
});
app_router.on(&#39;route:downloadFile&#39;, function( path ){ 
 alert(path); // 匹配后,整个匹配结果作为一个参数返回,路径为 user/images/hey.gif 
});
app_router.on(&#39;route:loadView&#39;, function( route, action ){ 
 alert(route + "_" + action); // 匹配后,传递过来两个参数,此时会弹出 dashboard_graph 
});

You may often hear the word "router", but it often refers to a network device that is used for network connection and data transmission. Navigation and hub. The "router" function in Backbone is similar to it. As you can see from the above example, it can navigate different URL anchors to the corresponding Action methods.
(Many server-side web frameworks also provide such a mechanism, but Backbone.Router focuses more on the navigation of front-end single-page applications.)

Backbone's routing navigation is composed of Backbone.Router and Backbone.History What the two classes accomplish together:

The Router class is used to define and parse routing rules, and map URLs to Actions.

The History class is used to monitor URL changes and trigger the Action method.

We generally do not instantiate a History directly, because when we create a Router instance for the first time, we will automatically create a singleton object of History. You can access this object through Backbone.history.

To use the routing function, first we need to define a Router class to declare the URL rules and Actions that need to be monitored. In the example just now, we define the list of URLs that need to be monitored through the routes attribute when defining, where Key represents the URL rule, and Value represents the Action method executed when the URL is in the rule.

Hash rules
URL rules represent the Hash (anchor) fragment in the current URL. In addition to specifying general strings in the rules, we also need to pay attention to two special dynamic rules:
A string separated by / (slash) in the rule will be converted into an expression ([^\/]+) inside the Router class, which represents multiple characters starting with / (slash). If If: (colon) is set in this rule, it means that this string in the URL will be passed to the Action as a parameter.
For example, we set the rule topic/:id. When the anchor point is #topic/1023, 1023 will be passed to the Action as the parameter id. The parameter name (:id) in the rule will generally be the same as the formal parameter of the Action method. The names are the same. Although Router does not have such a restriction, it is easier to understand using the same parameter names.
The * (asterisk) in the rule will be converted into an expression (.*?) inside the Router, which represents zero or more arbitrary characters. Compared with the : (colon) rule, * (asterisk) does not / (slash) separated limits, just like the *error rule we defined in the example above.
The * (asterisk) rule in Router uses non-greedy mode after being converted to a regular expression, so you can use a combination rule such as: *type/:id, which matches #hot/1023, and Hot and 1023 will be passed to the Action method as parameters.

The above describes how to define rules. These rules will correspond to an Action method name, which must be in the Router object.
After defining the Router class, we need to instantiate a Router object and call the start() method of the Backbone.history object, which will start monitoring the URL. Inside the History object, changes in the Hash (anchor) in the URL will be monitored by default through the onhashchange event. For browsers that do not support the onhashchange event (such as IE6), History will listen through the setInterval heartbeat.

pushState rules
Backbone.History also supports pushState URLs. pushState is a new feature provided by HTML5. It can operate the URL of the current browser (instead of just changing the anchor point) without changing the anchor point. Will cause the page to refresh, making the single-page application feel more like a complete process.
To use the pushState feature, you need to first understand some of the methods and events provided by HTML5 for this feature (these methods are defined in the window.history object):

1.pushState():该方法可以将指定的URL添加一个新的history实体到浏览器历史里
2.replaceState():该方法可以将当前的history实体替换为指定的URL

调用pushState()和replaceState()方法,仅仅是替换当前页面的URL,而并不会真正转到这个URL地址(当使用后退或前进按钮时,也不会跳转到该URL),我们可以通过onpopstate事件来监听这两个方法引起的URL变化。

路由相关方法

1.route()方法
在设定好路由规则之后,如果需要动态调整,可以调用Router.route()方法来动态添加路由规则及Action方法,例如:

router.route(&#39;topic/:pageno/:pagesize&#39;, &#39;page&#39;, function(pageno, pagesize){ 
 // todo 
}); 
我们调用route()方法时,给定的规则不仅仅可以是字符串,也可以是一个正则表达式:
router.route(/^topic/(.*?)/(.*?)$/, &#39;page&#39;, function(pageno, pagesize){ 
 // todo 
});

2.navigate()方法
在前面的例子中,URL规则都是由我们手动输入触发的,在实际应用中,有时可能需要手动进行跳转、导航,这时可以调用

Router.navigate()方法进行控制,例如:
router.navigate(&#39;topic/1000&#39;, {
 trigger: true
});

这段代码将URL更改为http://localhost/index.html#topic/1000,并触发了renderDetail方法。需要注意的是,我们在第二个参数传入了trigger配置,该配置用于表示更改URL的同时是否触发相应的Action方法。

3.stop()方法
还记得我们是通过Backbone.history.start()方法来启动路由监听的,你也可以随时调用Backbone.history.stop()方法来停止监听,例如:

router.route(&#39;topic/:pageno/:pagesize&#39;, &#39;page&#39;, function(pageno, pagesize) {
 Backbone.history.stop();
});

运行这段代码,并访问URL:http://localhost/index.html#topic/5/20,你会发现这个Action被执行之后,监听已经不再生效了。

更多全面解析JavaScript的Backbone.js框架中的Router路由相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn