用于完全 ajax 网站中不同动态加载内容的 JS
JS for different dynamically loaded content in a fully ajaxed website
这是一个完全更新的post,用改进的概念和代码(基于目前为止给出的答案)以更好的方式解释问题
我尝试实现一个完全 ajax 的网站,但我遇到了多个绑定事件的问题。
这是基本的HTML:
<header id="navigation">
<ul>
<li class="red" data-type="cars">Get Cars</li>
<li class="red" data-type="vegetables">Get Vegetables</li>
</ul>
</header>
<div id="anything">
<section id="dymanic-content"></section>
</div>
导航是动态创建的(因为 #navigation
的内容可以用另一个导航替换),所以导航元素的绑定看起来像这样:
$('#navigation').off('click', '.red').on('click', '.red', function() {
var type = $(this).attr('data-type');
var data = { 'param': 'content', 'type': type };
ajaxSend(data);
});
网站内容也在动态加载。例如有两个不同的内容:
1:
<div id="vegetables">Here are some information about vegetables: <button>Anything</button></div>
2:
<div id="cars"><img src="car.jpg"></div>
在加载内容时,我还将加载一个特定的 JS 文件,其中包含此类内容所需的所有绑定。所以加载脚本看起来像这样:
var ajaxSend = function(data) {
$.ajax({ url: "script.php", type: "POST", data: data, dataType: "json" })
.done(function( json ) {
if (json.logged === false) { login(ajaxSend, data); }
else {
$.getScript( 'js/' + json.file + '.js' )
.done(function( script, textStatus ) {
$('#result').html(json.antwort);
});
}
});
}
当您传递所需结果类型的参数(即蔬菜或汽车)时,结果将显示在 #result
中。还将加载文件 cars.js 或 vegetables.js。
所以我的问题是避免多重事件绑定。我就是这样做的:
cars.js:
$('#result').off('mouseover', 'img').on('mouseover', 'img', function () {
// do anything
});
vegetables.js:
$('#result').off('click', 'button').on('click', 'button', function () {
// do anything
});
这是正确的方法吗?我认为使用 off()
只是一种解决方法。所以,如果有任何改进,我将不胜感激!
另外,如果用户多次点击导航,我不知道是否有问题: 那样的话,js文件被加载了多次,不是吗?那么这个概念有多重绑定吗?
您可以创建一个采用要加载的页面名称的函数,并使用单个函数来加载页面。然后让回调函数加载同名的 javascript 文件(具有通用的 init
函数)。喜欢:
function loadPage( pageName ) {
$('#dymanic-content').load( pageName +'.php', function() {
$.getScript( pageName +'.js', function() {
init();
});
});
}
或者您可以将回调函数名称传递给函数。
function loadPage( pageName, cb ) {
$('#dymanic-content').load( pageName +'.php', function() {
$.getScript( pageName +'.js', function() {
cb();
});
});
}
您也可以使用 promises 而不是回调来做到这一点。
如果您使用 AJAX 网络方式,请考虑使用 PJAX。它是用于创建 AJAX 网站的久经考验的库,并在 github.
上使用
下面使用 PJAX 的完整示例:
HTML:
一旦脚本加载完成,data-js 属性将用于 运行 我们的函数。每个页面都需要不同。
data-url-js 属性包含要加载的 JS 脚本列表。
<div id="content" data-js="vegetablesAndCars" data-urljs="['/js/library1.js','/js/vegetablesAndCars.js']">
<ul class="navigation">
<li><a href="to/link/1">Link 1</a></li>
<li><a href="to/link/2">Link 2</a></li>
</ul>
<div id="vegetables">
</div>
<div id="cars">
</div>
</div>
模板:您的所有页面都必须将 #content
div 作为容器,并具有上述两个属性。
JS:
App.js - 每个页面都需要包含此文件。
/*
* PJAX Global Defaults
*/
$.pjax.defaults.timeout = 30000;
$.pjax.defaults.container = "#content";
/*
* Loads JS scripts for each page
*/
function loadScript(scriptName, callback) {
var body = document.getElementsByTagName('body')[0];
$.each(scriptArray,function(key,scripturl){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scripturl;
// fire the loading
body.appendChild(script);
});
}
/*
* Execute JS script for current Page
*/
function executePageScript()
{
//Check if we have a script to execute
if(typeof document.getElementById('content').getAttribute('data-js') !== null)
{
var functionName = document.getElementById('content').getAttribute('data-js').toString();
if(typeof window[functionName] === "undefined")
{
var jsUrl = document.getElementById('content').getAttribute('data-url-js').toString();
if(typeof jsUrl !== "undefined")
{
jsLoader(JSON.parse(jsUrl));
}
else
{
console.log('Js Url not set');
}
}
else
{
//If script is already loaded, just execute the script
window[functionName]();
}
}
}
$(function(){
/*
* PJAX events
*/
$(document).on('pjax:success, pjax:end',function(){
//After Successful loading
//Execute Javascript
executePageScript();
}).on('pjax:beforeSend',function(){
//Before HTML replace. You might want to show a little spinning loader to your users here.
console.log('We are loading our stuff through pjax');
});
});
vegetableAndCars.js - 这是您的页面特定的 js 文件。您所有特定于页面的 js 脚本都必须遵循此模板。
/*
* Name: vegetablesAndCars Script
* Description: Self-executing function on document load.
*/
(window.vegetablesAndCars = function() {
$('#cars').on('click',function(){
console.log('Vegetables and cars dont mix');
});
$('.navigation a').on('click',function() {
//Loads our page through pjax, i mean, ajax.
$.pjax({url:$(this).attr('href')});
});
})();
更多解释:
一个函数名已经附加到window全局js命名空间,这样就可以在不重新加载脚本的情况下重新执行该函数。如您所知,此函数名称必须是唯一的。
该函数是自执行的,因此如果用户到达页面而不使用 AJAX(即直接进入页面 URL),它将自行执行.
您可能会问,我拥有 on
我的 HTML 元素的所有那些绑定呢?好吧,一旦元素是 destroyed/replaced,绑定到它们的代码将被浏览器垃圾收集。所以您的内存使用量不会飙升。
上述用于实现基于 ajax 的网站的模式,目前正在我的一个客户处进行生产。所以它已经针对所有场景进行了非常多的测试。
使用 .off(...).on(...)
方法,如果您有多个 .js 文件绑定到同一个事件(即:汽车和蔬菜都有不同的按钮点击,则可以保证在新绑定之前清除事件逻辑)。
但是,如果不是这种情况,您可以使用 class 过滤器来检测哪个元素已经有事件限制:
$('#result:not(.click-bound)').addClass('click-bound').on('click', 'button', function() {
// your stuff in here
});
这样选择器只会将事件绑定到尚未使用 class click-bound
.
修饰的元素
首先,我建议您像其他人建议的那样选择 AngularJS 这样的框架。
但是,除此之外,您还可以考虑使用 namespaces:
cars.js:
$('#result').off('mouseover.cars', 'img').on('mouseover.cars', 'img', function () {
// do anything
});
vegetables.js:
$('#result').off('click.vegetables', 'button').on('click.vegetables', 'button', function () {
// do anything
});
这将是一个改进 (并且解决方法会少一些),因为:
(It would do the work) without disturbing other click event handlers
attached to the elements.
当你在$('#navigation').on('some-event', '.red',function(){});
您将事件绑定到 #navigation
元素(您可以通过 $('#navigation').data('events')
看到这一点),而不是绑定到内部的 .red
元素,这就是为什么当您使用新的 js 逻辑加载新元素时您正在获得新旧绑定。
如果这在您的情况下可行,只需对所有应 removed/reloaded 与元素一起的事件使用直接绑定,例如 $('#navigation .red').some-event(function(){});
。
cars.js:
$('#result').off('mouseover', 'img').on('mouseover', 'img', function () {
// do anything
});
vegetabels.js:
$('#result').off('click', 'button').on('click', 'button', function () {
// do anything
});
我不确定,但是,如果用户首先点击导航上的汽车类型,然后 ('mouseover', 'img')
听众取消注册然后重新注册,对吗?
然后当用户点击导航上的蔬菜类型 ('click', 'button')
- 取消注册(但是!!! 'mouseover', 'img'
- 被保留!!!),然后如果用户点击某种类型的导航,其中脚本没有 ('mouseover', 'img')
侦听器但内容有 img - 然后出现非法内容侦听器(从之前的操作开始)。
因此,在开始加载新内容和脚本之前,您需要清除所有已注册到 #result
的侦听器,也许:
var ajaxSend = function(data) {
$.ajax({ url: "script.php", type: "POST", data: data, dataType: "json" })
.done(function( json ) {
if (json.logged === false) { login(ajaxSend, data); }
else {
$('#result').off();
$.getScript( 'js/' + json.file + '.js' )
.done(function( script, textStatus ) {
$('#result').html(json.antwort);
});
}
});
}
或
cars.js:
$('#result').off().on('mouseover', 'img', function () {
// do anything
});
vegetabels.js:
$('#result').off().on('click', 'button', function () {
// do anything
});
编辑: 关于多次加载脚本。我没有找到明确的答案,我认为这取决于浏览器和 jquery 实现,并且每次创建新脚本时都有可能创建新脚本,即使它是较早创建的,所以可能有 2缺点:
- 重复加载相同的脚本表单服务器,如果不是浏览器,也不是 jquery 没有缓存它
- 通过脚本淹没 DOM anp 浏览器的解释器
但是,取决于 JQuery 文档。
Caching Responses
By default, $.getScript()
sets the cache setting to false
. This appends a timestamped query parameter to the request URL to ensure that the browser downloads the script each time it is requested. You can override this feature by setting the cache property globally using $.ajaxSetup()
$.ajaxSetup({ cache: true });
您可以依赖 JQuery cache (there is an option to cache only scripts),或实现您自己的,例如:
var scriptCache = [];
function loadScript(scriptName, cb){
if (scriptCache[scriptName]) {
jQuery.globalEval(scriptCache[scriptName]);
cb();
} else {
$.getScript( scriptName )
.done(function( script, textStatus ) {
scriptCache[scriptName] = script;
//$('#result').html(json.antwort);
cb();
});
}
}
在大多数情况下,您可能想象的在 Web 开发中所做的一切都已经完成。您只需要找到它并让它与您的环境一起工作。您的代码存在许多问题,但还有其他问题更让我困扰 - 为什么没有人提到 angularJS or requireJS?使用此类框架和库有很大的好处,其中包括
- 到处都有数以千计的教程
- 关于 SO 的成千上万个问题
- 他们(大部分)有很棒的插件,随时可以使用
- 与您的实现相比,它们可能具有更广泛的功能
此外还有使用您自己的代码的好处
- 只有你一个人看得懂
- 有什么吗?
我的观点是你应该使用别人已经构建的东西,在 99% 的情况下是完全免费的。
另外使用像 angular 这样的框架,您最终将拥有更清晰和可维护的代码。
当你提到一个一个完全ajax的网站时,我认为一个SPA -- S单身P年龄A申请.
区别可能是语义上的,但是AJAX意味着DOM操纵,而SPA 意味着 Templating 和 Navigation。
HTML 模板会在您的页面加载时加载。每个模板映射到特定的导航路线。主要变化不是事件映射,而是显示模板以及是否已加载新数据。
See my example AngularJS SPA Plunkr
AngularJS 路由如下所示:
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'pages/home.html',
controller: 'mainController'
})
// route for the cars page
.when('/cars', {
templateUrl: 'pages/Cars.html',
controller: 'CarsController'
})
// route for the vegetables page
.when('/vegetables', {
templateUrl: 'pages/Vegetables.html',
controller: 'VegetablesController'
});
});
所以每条路由都有对应的HTMLTemplate和Controller(这里定义了回调函数)
出于 CDN 目的,模板可以作为 JSON
传回
// route for the vegetables page
.when('/vegetables', {
template: '<div class="jumbotron text-center"><div class="row"><h3>Cars Page</h3>Available Cars: <a class="btn btn-primary" ng-click='LoadCars()'>LoadCars</a></div><div class="col-sm-4"><a class="btn btn-default" ng-click="sort='name'"> Make/Model</a></div><div class="col-sm-2"><a class="btn btn-default" ng-click="sort='year'"> Year</a></div><div class="col-sm-2"><a class="btn btn-default" ng-click="sort='price'"> Price</a></div><div class="row" ng-repeat="car in cars | orderBy:sort"><div class="row"></div><div class="col-sm-4">{{ car.name }}</div><div class="col-sm-2">{{ car.year }}</div><div class="col-sm-2">${{ car.price }}</div></div></div>',
controller: 'VegetablesController'
});
在"templated"个应用程序中,每个类型HTML加载一次。
事件和控件绑定一次。
增量变化是JSON来回传递。您的端点不负责渲染 HTML。它们可以是 restful 并且存在明确的关注点分离。
您可以使用 AngularJS、[= 创建模板化 SPA 应用程序35=]Ember,Backbone, JQuery,等等。
这是一个完全更新的post,用改进的概念和代码(基于目前为止给出的答案)以更好的方式解释问题
我尝试实现一个完全 ajax 的网站,但我遇到了多个绑定事件的问题。
这是基本的HTML:
<header id="navigation">
<ul>
<li class="red" data-type="cars">Get Cars</li>
<li class="red" data-type="vegetables">Get Vegetables</li>
</ul>
</header>
<div id="anything">
<section id="dymanic-content"></section>
</div>
导航是动态创建的(因为 #navigation
的内容可以用另一个导航替换),所以导航元素的绑定看起来像这样:
$('#navigation').off('click', '.red').on('click', '.red', function() {
var type = $(this).attr('data-type');
var data = { 'param': 'content', 'type': type };
ajaxSend(data);
});
网站内容也在动态加载。例如有两个不同的内容:
1:
<div id="vegetables">Here are some information about vegetables: <button>Anything</button></div>
2:
<div id="cars"><img src="car.jpg"></div>
在加载内容时,我还将加载一个特定的 JS 文件,其中包含此类内容所需的所有绑定。所以加载脚本看起来像这样:
var ajaxSend = function(data) {
$.ajax({ url: "script.php", type: "POST", data: data, dataType: "json" })
.done(function( json ) {
if (json.logged === false) { login(ajaxSend, data); }
else {
$.getScript( 'js/' + json.file + '.js' )
.done(function( script, textStatus ) {
$('#result').html(json.antwort);
});
}
});
}
当您传递所需结果类型的参数(即蔬菜或汽车)时,结果将显示在 #result
中。还将加载文件 cars.js 或 vegetables.js。
所以我的问题是避免多重事件绑定。我就是这样做的:
cars.js:
$('#result').off('mouseover', 'img').on('mouseover', 'img', function () {
// do anything
});
vegetables.js:
$('#result').off('click', 'button').on('click', 'button', function () {
// do anything
});
这是正确的方法吗?我认为使用 off()
只是一种解决方法。所以,如果有任何改进,我将不胜感激!
另外,如果用户多次点击导航,我不知道是否有问题: 那样的话,js文件被加载了多次,不是吗?那么这个概念有多重绑定吗?
您可以创建一个采用要加载的页面名称的函数,并使用单个函数来加载页面。然后让回调函数加载同名的 javascript 文件(具有通用的 init
函数)。喜欢:
function loadPage( pageName ) {
$('#dymanic-content').load( pageName +'.php', function() {
$.getScript( pageName +'.js', function() {
init();
});
});
}
或者您可以将回调函数名称传递给函数。
function loadPage( pageName, cb ) {
$('#dymanic-content').load( pageName +'.php', function() {
$.getScript( pageName +'.js', function() {
cb();
});
});
}
您也可以使用 promises 而不是回调来做到这一点。
如果您使用 AJAX 网络方式,请考虑使用 PJAX。它是用于创建 AJAX 网站的久经考验的库,并在 github.
上使用下面使用 PJAX 的完整示例:
HTML:
一旦脚本加载完成,data-js 属性将用于 运行 我们的函数。每个页面都需要不同。
data-url-js 属性包含要加载的 JS 脚本列表。
<div id="content" data-js="vegetablesAndCars" data-urljs="['/js/library1.js','/js/vegetablesAndCars.js']">
<ul class="navigation">
<li><a href="to/link/1">Link 1</a></li>
<li><a href="to/link/2">Link 2</a></li>
</ul>
<div id="vegetables">
</div>
<div id="cars">
</div>
</div>
模板:您的所有页面都必须将 #content
div 作为容器,并具有上述两个属性。
JS:
App.js - 每个页面都需要包含此文件。
/*
* PJAX Global Defaults
*/
$.pjax.defaults.timeout = 30000;
$.pjax.defaults.container = "#content";
/*
* Loads JS scripts for each page
*/
function loadScript(scriptName, callback) {
var body = document.getElementsByTagName('body')[0];
$.each(scriptArray,function(key,scripturl){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scripturl;
// fire the loading
body.appendChild(script);
});
}
/*
* Execute JS script for current Page
*/
function executePageScript()
{
//Check if we have a script to execute
if(typeof document.getElementById('content').getAttribute('data-js') !== null)
{
var functionName = document.getElementById('content').getAttribute('data-js').toString();
if(typeof window[functionName] === "undefined")
{
var jsUrl = document.getElementById('content').getAttribute('data-url-js').toString();
if(typeof jsUrl !== "undefined")
{
jsLoader(JSON.parse(jsUrl));
}
else
{
console.log('Js Url not set');
}
}
else
{
//If script is already loaded, just execute the script
window[functionName]();
}
}
}
$(function(){
/*
* PJAX events
*/
$(document).on('pjax:success, pjax:end',function(){
//After Successful loading
//Execute Javascript
executePageScript();
}).on('pjax:beforeSend',function(){
//Before HTML replace. You might want to show a little spinning loader to your users here.
console.log('We are loading our stuff through pjax');
});
});
vegetableAndCars.js - 这是您的页面特定的 js 文件。您所有特定于页面的 js 脚本都必须遵循此模板。
/*
* Name: vegetablesAndCars Script
* Description: Self-executing function on document load.
*/
(window.vegetablesAndCars = function() {
$('#cars').on('click',function(){
console.log('Vegetables and cars dont mix');
});
$('.navigation a').on('click',function() {
//Loads our page through pjax, i mean, ajax.
$.pjax({url:$(this).attr('href')});
});
})();
更多解释:
一个函数名已经附加到window全局js命名空间,这样就可以在不重新加载脚本的情况下重新执行该函数。如您所知,此函数名称必须是唯一的。
该函数是自执行的,因此如果用户到达页面而不使用 AJAX(即直接进入页面 URL),它将自行执行.
您可能会问,我拥有 on
我的 HTML 元素的所有那些绑定呢?好吧,一旦元素是 destroyed/replaced,绑定到它们的代码将被浏览器垃圾收集。所以您的内存使用量不会飙升。
上述用于实现基于 ajax 的网站的模式,目前正在我的一个客户处进行生产。所以它已经针对所有场景进行了非常多的测试。
使用 .off(...).on(...)
方法,如果您有多个 .js 文件绑定到同一个事件(即:汽车和蔬菜都有不同的按钮点击,则可以保证在新绑定之前清除事件逻辑)。
但是,如果不是这种情况,您可以使用 class 过滤器来检测哪个元素已经有事件限制:
$('#result:not(.click-bound)').addClass('click-bound').on('click', 'button', function() {
// your stuff in here
});
这样选择器只会将事件绑定到尚未使用 class click-bound
.
首先,我建议您像其他人建议的那样选择 AngularJS 这样的框架。
但是,除此之外,您还可以考虑使用 namespaces:
cars.js:
$('#result').off('mouseover.cars', 'img').on('mouseover.cars', 'img', function () {
// do anything
});
vegetables.js:
$('#result').off('click.vegetables', 'button').on('click.vegetables', 'button', function () {
// do anything
});
这将是一个改进 (并且解决方法会少一些),因为:
(It would do the work) without disturbing other
clickevent handlers attached to the elements.
当你在$('#navigation').on('some-event', '.red',function(){});
您将事件绑定到 #navigation
元素(您可以通过 $('#navigation').data('events')
看到这一点),而不是绑定到内部的 .red
元素,这就是为什么当您使用新的 js 逻辑加载新元素时您正在获得新旧绑定。
如果这在您的情况下可行,只需对所有应 removed/reloaded 与元素一起的事件使用直接绑定,例如 $('#navigation .red').some-event(function(){});
。
cars.js:
$('#result').off('mouseover', 'img').on('mouseover', 'img', function () { // do anything });
vegetabels.js:
$('#result').off('click', 'button').on('click', 'button', function () { // do anything });
我不确定,但是,如果用户首先点击导航上的汽车类型,然后 ('mouseover', 'img')
听众取消注册然后重新注册,对吗?
然后当用户点击导航上的蔬菜类型 ('click', 'button')
- 取消注册(但是!!! 'mouseover', 'img'
- 被保留!!!),然后如果用户点击某种类型的导航,其中脚本没有 ('mouseover', 'img')
侦听器但内容有 img - 然后出现非法内容侦听器(从之前的操作开始)。
因此,在开始加载新内容和脚本之前,您需要清除所有已注册到 #result
的侦听器,也许:
var ajaxSend = function(data) {
$.ajax({ url: "script.php", type: "POST", data: data, dataType: "json" })
.done(function( json ) {
if (json.logged === false) { login(ajaxSend, data); }
else {
$('#result').off();
$.getScript( 'js/' + json.file + '.js' )
.done(function( script, textStatus ) {
$('#result').html(json.antwort);
});
}
});
}
或
cars.js:
$('#result').off().on('mouseover', 'img', function () {
// do anything
});
vegetabels.js:
$('#result').off().on('click', 'button', function () {
// do anything
});
编辑: 关于多次加载脚本。我没有找到明确的答案,我认为这取决于浏览器和 jquery 实现,并且每次创建新脚本时都有可能创建新脚本,即使它是较早创建的,所以可能有 2缺点:
- 重复加载相同的脚本表单服务器,如果不是浏览器,也不是 jquery 没有缓存它
- 通过脚本淹没 DOM anp 浏览器的解释器
但是,取决于 JQuery 文档。
Caching Responses
By default,
$.getScript()
sets the cache setting tofalse
. This appends a timestamped query parameter to the request URL to ensure that the browser downloads the script each time it is requested. You can override this feature by setting the cache property globally using$.ajaxSetup()
$.ajaxSetup({ cache: true });
您可以依赖 JQuery cache (there is an option to cache only scripts),或实现您自己的,例如:
var scriptCache = [];
function loadScript(scriptName, cb){
if (scriptCache[scriptName]) {
jQuery.globalEval(scriptCache[scriptName]);
cb();
} else {
$.getScript( scriptName )
.done(function( script, textStatus ) {
scriptCache[scriptName] = script;
//$('#result').html(json.antwort);
cb();
});
}
}
在大多数情况下,您可能想象的在 Web 开发中所做的一切都已经完成。您只需要找到它并让它与您的环境一起工作。您的代码存在许多问题,但还有其他问题更让我困扰 - 为什么没有人提到 angularJS or requireJS?使用此类框架和库有很大的好处,其中包括
- 到处都有数以千计的教程
- 关于 SO 的成千上万个问题
- 他们(大部分)有很棒的插件,随时可以使用
- 与您的实现相比,它们可能具有更广泛的功能
此外还有使用您自己的代码的好处
- 只有你一个人看得懂
- 有什么吗?
我的观点是你应该使用别人已经构建的东西,在 99% 的情况下是完全免费的。
另外使用像 angular 这样的框架,您最终将拥有更清晰和可维护的代码。
当你提到一个一个完全ajax的网站时,我认为一个SPA -- S单身P年龄A申请.
区别可能是语义上的,但是AJAX意味着DOM操纵,而SPA 意味着 Templating 和 Navigation。
HTML 模板会在您的页面加载时加载。每个模板映射到特定的导航路线。主要变化不是事件映射,而是显示模板以及是否已加载新数据。
See my example AngularJS SPA Plunkr
AngularJS 路由如下所示:
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'pages/home.html',
controller: 'mainController'
})
// route for the cars page
.when('/cars', {
templateUrl: 'pages/Cars.html',
controller: 'CarsController'
})
// route for the vegetables page
.when('/vegetables', {
templateUrl: 'pages/Vegetables.html',
controller: 'VegetablesController'
});
});
所以每条路由都有对应的HTMLTemplate和Controller(这里定义了回调函数)
出于 CDN 目的,模板可以作为 JSON
传回 // route for the vegetables page
.when('/vegetables', {
template: '<div class="jumbotron text-center"><div class="row"><h3>Cars Page</h3>Available Cars: <a class="btn btn-primary" ng-click='LoadCars()'>LoadCars</a></div><div class="col-sm-4"><a class="btn btn-default" ng-click="sort='name'"> Make/Model</a></div><div class="col-sm-2"><a class="btn btn-default" ng-click="sort='year'"> Year</a></div><div class="col-sm-2"><a class="btn btn-default" ng-click="sort='price'"> Price</a></div><div class="row" ng-repeat="car in cars | orderBy:sort"><div class="row"></div><div class="col-sm-4">{{ car.name }}</div><div class="col-sm-2">{{ car.year }}</div><div class="col-sm-2">${{ car.price }}</div></div></div>',
controller: 'VegetablesController'
});
在"templated"个应用程序中,每个类型HTML加载一次。
事件和控件绑定一次。
增量变化是JSON来回传递。您的端点不负责渲染 HTML。它们可以是 restful 并且存在明确的关注点分离。
您可以使用 AngularJS、[= 创建模板化 SPA 应用程序35=]Ember,Backbone, JQuery,等等。