`
icekiller110
  • 浏览: 72319 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ember translation

阅读更多

本文为原创,转载请注明出处。

 

简介................................................................................

什么是Ember.js.................................................................

消除样板文件.....................................................................

提供的架构........................................................................

Ember与众不同在哪些地方....................................................

Ember.js 概览..................................................................

绑定:.............................................................................

计算出的属性:..................................................................

自动更新的模版:...............................................................

入门指南..........................................................................

Ember的对象模型..............................................................

子类化类.........................................................................

重新打开类和实例..............................................................

计算出的属性(取值器).........................................................

计算出的属性(设值器).........................................................

监听器...........................................................................

数组中的变化...................................................................

绑定..............................................................................

单向绑定.........................................................................

什么时候使用....................................................................

创建一个命名空间...............................................................

使用Handlebars描述你的UI..................................................

Handlebars.....................................................................

Ember.view....................................................................

Handlerbars基础..............................................................

{{#if}}, {{else}}, {{#unless}}.....................................

{{#with}}.....................................................................

使用{{bindAttr}}绑定元素属性.............................................

使用{{bindAttr}}绑定类(css的类)名字....................................

使用{{action}}处理事件.....................................................

构建层级视图....................................................................

{{view}}.......................................................................

设置子视图模版.................................................................

设置绑定.........................................................................

修改视图的HTML...............................................................

显示列表元素....................................................................

书写自定义助手:...............................................................

视图包含的控件..................................................................

深入视图..........................................................................

处理事件..........................................................................

使用Ember.ContainerView人工管理视图..................................

渲染管道..........................................................................

定制HTML元素...................................................................

视图上的属性绑定...............................................................

Ember的可枚举的API.........................................................

什么是可枚举的.................................................................

Ember中可枚举的.............................................................

可枚举接口......................................................................

参数:...........................................................................

第一个和最后一个..............................................................

转换为数组......................................................................

转换..............................................................................

每个对象的设值器和取值器...................................................

过滤..............................................................................

汇总信息 (all any).........................................................

 

简介

什么是Ember.js

Ember是一个用来创建雄心勃勃的web应用程序的JS框架,它消除了样本文件并且提供一个标准的应用程序架构。

消除样板文件

对于每一个web应用程序都有一些通用的任务。例如:从服务器取得数据,渲染数据到屏幕上,然后当数据变更的时候更新显示信息。

 

因为浏览器提供的做这件事情的工具很原始,你最终要一遍又一遍的编写相同的代码。Ember.js提供了一些工具,让你专注于你的应用程序,而不是书写100遍相同的代码。

 

因为我们已经建立的许多我们自己的应用程序,我们已经超越了明显低级别的事件抽象驱动的抽象,消除大部分整个应用程序中传播变化的关联引用的样板文件,尤其是到DOM本身。

 

为了辅助管理视图中的变化,Ember.js 带有一个模版引擎,当底层对象改变后可以自动的更新DOM

 

一个简单的例子,思考如下Person的模版。

 

{{person.name}} is {{person.age}}.

与任何模版系统一样,当模版初始化渲染后,它将反射出Person的当前状态。Ember.js 不仅消除了样板文件,还会在某人的姓名和年龄变化后自动的更新DOM

 

指定模版一次,Ember.js 就会保证它总是最新的。

提供的架构

由于应用程序是从Web页面(静态文件)演进来的,浏览器提供了仅仅够用的接口。

 

Ember很容易将你的应用程序划分成原型、视图和控制器, 这提高了可测试性,使代码更加模块化,并帮助当前项目的新开发人员迅速理解项目是怎么在一起运作的。回调的日子结束了。

 

Ember还提供内置支持的状态管理,所以你有一种方式来描述你的应用程序在各种嵌套状态的中的迅速转换。

 

Ember与众不同在哪些地方

传统的web应用程序让用户每次与服务器交互下载一个新的页面。这意味着每次交互都不会比你和用户的等待时间快,通常很慢。使用AJAX替换页面的一部分会有些许帮助,但是你的UI需要更新时候,仍然必须每次需要到Server的一次往返。还有,如果页面的多个部分需要一次更新多个部分,大多数开发人员只是再次重新加载页面一次,因为保持一切同步是很棘手的。

 

Ember.js,像其他一些现代JavaScript框架差不多,略有差异。和大多数将逻辑放在服务器上的应用程序不同的是,Ember.js应用程序会在页面加载完毕后下载运行时需要的所有东西。那就意味着使用你的应用程序的用户从来不需要加载一个新的页面,并且你同他们交互的UI是快速的。

 

这个架构的一个优势是,你的应用程序使用相同的REST API或是第三方客户端作为你的本地应用。后台开发人员可以专注于开发快速、可靠和安全的API服务端,并且不需要前端专家的参与。

Ember.js 概览

有三个特性,使得你乐于使用Ember

 

绑定

计算出的属性

模版自动更新

绑定:

使用绑定可以是两个不同对象的属性保持同步。你只需要声明一次绑定,然后Ember会确保变化在所有位置进行传播。

 

以下是如何创建一个对于两个对象的绑定:

1

2

3

4

5

6

7

8

9

10

11

MyApp.president = Ember.Object.create({

  name: "Barack Obama"

});

MyApp.country = Ember.Object.create({

  // Ending a property with 'Binding' tells Ember to

  // create a binding to the presidentName property.

  presidentNameBinding: 'MyApp.president.name'

});

// Later, after Ember has resolved bindings...

MyApp.country.get('presidentName');

// "Barack Obama"

绑定允许你构建你的应用程序使用MVC模式,然后Rest很容易知道数据将一直正确的在层与层之间传输。

计算出的属性:

计算出的属性允许你像一个属性一样对待一个function

1

2

3

4

5

6

7

8

9

10

MyApp.president = Ember.Object.create({

  firstName: "Barack",

  lastName: "Obama",

  fullName: function() {

    returnthis.get('firstName') + '' + this.get('lastName');

  // Call this flag to mark the function as a property

  }.property()

});

MyApp.president.get('fullName');

// "Barack Obama"

计算出的属性是有用的,因为它们可以和binding一起协作,就像其他的属性一样。

 

许多计算出的属性依赖于其他属性。例如,在上面的例子中,fullName属性依赖firstNamelastName来确定它的值。你可以告诉Ember关于这些依赖,像这样:

 

1

2

3

4

5

6

7

8

9

MyApp.president = Ember.Object.create({

  firstName: "Barack",

  lastName: "Obama",

  fullName: function() {

    returnthis.get('firstName') + '' + this.get('lastName');

  // Tell Ember that this computed property depends on firstName

  // and lastName

  }.property('firstName', 'lastName')

});

自动更新的模版:

Ember使用Handlebars(一个语义化的模版库)。从你的JS 应用程序取得数据,然后把它带进DOM,创建一个<script>标签,把它放到你的HTML中任何你想要让你的值出现的地方:

1

2

3

<script type="text/x-handlebars">

  The President of the United States is {{MyApp.president.fullName}}.

</script>

这是最好的部分:模版是有意识的绑定。就是说,如果你曾经改变那些用来显示的属性的值,我们将为你自动更新它。因为你已经指定了依赖,改变这些属性也会被很好的反映出来。

 

希望你可以看清这三个强大的工具是怎么在一起协作的:以一些原始属性开始,然后开始构建更复杂的属性和包含依赖的的计算出的属性。一旦你已经完成了数据的表示,你只需要说明他是如何展现一次的,然后Ember会关注剩下的。不管底层数据的如何变化,无论是来自XHR请求或用户执行操作,你的用户界面总是保持最新的。这就消除了开发人员每天都在努力的所有边缘情况的用例

入门指南

根据你的需求,这有几种方法来创建你的一个Ember.js 应用。

 

如果你的需求简单或者你的兴趣只是玩一玩,你可以下载Ember.js的入门工具。它是基于HTML5 样板的,并且没有引入任何构建工具和其他依赖。首先,下载Starter Kit并且解压它,然后你可以直接在index.html文件中直接编辑Handlebars模版,Ember.js的应用程序本身是 javascripts/app.js.

 

对于大型应用程序,你可能需要考虑使用Ruby on RailsRails能帮助您管理您的源代码和其它的资产,同时也提供你的应用程序之间通信使用的REST API

Ember的对象模型

Ember增强了简单的JavaScript对象模型来支持绑定、监听器和支持一个强大的基于mixin的来共享代码的方法。

 

作为最基本的,你使用Ember.Objectextend方法来创建一个Ember的类。

1

2

3

4

5

Person = Ember.Object.extend({

  say: function(thing) {

    alert(thing);

 }

});

一旦你构建了一个新的类,你可以使用create方法来创建类的实例。任何在类上定义的方法都可以在实例上使用。

1

2

var person = Person.create();

person.say("Hello") // alerts "Hello"

当创建实例的时候,你也可以通过对象本身添加额外的属性到实例。

1

2

3

4

5

6

7

var tom = Person.create({

  name: "Tom Dale",

  helloWorld: function() {

    this.say("Hi my name is " + this.get('name'));

  }

});

tom.helloWorld() // alerts "Hi my name is Tom Dale"

因为Ember支持绑定和监听器,所以你总是可以使用get方法访问属性和使用set方法设置属性。

 

当创建一个对象的实例的时候,你也可以覆盖类所定义的任何属性和方法。例如,这个例子中,你覆盖了来自Person类的say方法:

1

2

3

4

5

6

7

var yehuda = Person.create({

  name: "Yehuda Katz",

  say: function(thing) {

    var name = this.get('name');

    this._super(name + " says: " + thing);

  }

});

你可以使用对象的_super方法来调用被你覆盖的原始方法。(superJS的保留字)

 

子类化类

你也可以使用extend方法创建类的子类。事实上,当我们调用Ember.Objectextend方法创建一个新的类,我们已经是Ember.Object的子类了。

 

1

2

3

4

5

var LoudPerson = Person.extend({

  say: function(thing) {

    this._super(thing.toUpperCase());

  }

});

当子类化的时候,你可以使用this._super来调用你要覆盖的父类方法。

 

重新打开类和实例

你不需要一下就定义好类的所有东西。你可以使用reopen方法重新打开类定义新属性。

1

2

3

4

Person.reopen({

  isPerson: true

});

Person.create().get('isPerson') // true

当使用reopen的时候,你也可以使用this._super覆盖已经存在的方法。

 

正如你看见的那样,reopen用来给一个实例添加属性和方法。但是当你需要创建类方法或者添加类属性,你可以使用reopenClass

1

2

3

4

5

6

Person.reopenClass({

  createMan: function() {

    return Person.create({isMan: true})

  }

});

Person.createMan().get('isMan') // true

计算出的属性(取值器)

经常,你想要一个属性是基于其他属性计算来的。Ember的对象模型允许你在一个普通的类定义中很容易的定义计算出的属性。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Person = Ember.Object.extend({

  // these will be supplied by `create`

  firstName: null,

  lastName: null,

  fullName: function() {

    var firstName = this.get('firstName');

    var lastName = this.get('lastName');

   return firstName + '' + lastName;

  }.property('firstName', 'lastName')

});

var tom = Person.create({

  firstName: "Tom",

  lastName: "Dale"

});

tom.get('fullName') // "Tom Dale"

property方法定义function作为一个计算出的属性并且定义它的依赖。那些依赖将会再稍后我们讨论绑定和监听器的时候起作用。

 

当子类化一个类或者创建一个类的实例的时候,你可以覆盖任何计算出的属性。

 

计算出的属性(设值器)

你也可以定义当设置一个计算出的属性的时候Ember可以做什么。如果你试图设置一个计算出的属性,它将在你设置它的时候带着它的keyvalue被调用。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Person = Ember.Object.extend({

  // these will be supplied by `create`

  firstName: null,

  lastName: null,

  fullName: function(key, value) {

    // getter

    if (arguments.length === 1) {

      var firstName = this.get('firstName');

      var lastName = this.get('lastName');

      return firstName + '' + lastName;

    // setter

    } else {

      var name = value.split("");

      this.set('firstName', name[0]);

      this.set('lastName', name[1]);

      return value;

    }

  }.property('firstName', 'lastName')

});

var person = Person.create();

person.set('fullName', "Peter Wagenet");

person.get('firstName') // Peter

person.get('lastName') // Wagenet

Ember将会同时调用计算出的属性的settersgetters,根据传进来的参数数目决定getter或是setter的调用。

 

监听器

Ember支持监听任何属性,包含计算出的属性。你可以使用addObserver方法来给一个对象添加监听器。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Person = Ember.Object.extend({

  // these will be supplied by `create`

  firstName: null,

  lastName: null,

  fullName: function() {

    var firstName = this.get('firstName');

    var lastName = this.get('lastName');

    return firstName + '' + lastName;

  }.property('firstName', 'lastName')

});

var person = Person.create({

  firstName: "Yehuda",

  lastName: "Katz"

});

person.addObserver('fullName', function() {

  // deal with the change

});

person.set('firstName', "Brohuda"); // observer will fire

因为计算出的属性fullName依赖于firstName,所以更新firstName也会触发fullName的监听器。

 

因为监听器很通用,Ember提供了一种内联在class定义上的定义方式。

1

2

3

4

5

Person.reopen({

  fullNameChanged: function() {

    // this is an inline version of .addObserver

  }.observes('fullName')

});

如果你使用Ember没有对原型进行扩展,可以使用Ember.observer方法定义内联监听器。

1

2

3

4

5

Person.reopen({

  fullNameChanged: Ember.observer(function() {

    // this is an inline version of .addObserver

  }, 'fullName')

});

数组中的变化

经常,你可能有一个计算出的属性依赖于一个数组中的所有元素来确定它的值。例如,你可能想要统计一个控制器中的所有todo的元素来确定他们完成的多少。

 

那个计算出的属性可能是如下:

1

2

3

4

5

6

7

8

9

App.todosController = Ember.Object.create({

  todos: [

    Ember.Object.create({ isDone: false })

  ],

  remaining: function() {

    var todos = this.get('todos');

    return todos.filterProperty('isDone', false).get('length');

  }.property('todos.@each.isDone')

});

注意:依赖的键(todos.@each.isDone)包含了特殊的键@each。这个会在以下四种事件中的一种发生后通知Ember.js更新绑定和触发监听器。

 

todos数组中的任意个一个对象的isDone属性发生变化。

一个元素被添加到todos数组。

一个元素从todos数组被删除。

控制器的todos属性改变成一个不同的数组。

 

上面的例子中,remaining的统计值是1

1

2

App.todosController.get('remaining');

// 1

如果我们改变todoisDone属性,remaining属性将被自动更新:

1

2

3

4

5

6

7

8

9

var todos = App.todosController.get('todos');

var todo = todos.objectAt(0);

todo.set('isDone', true);

App.todosController.get('remaining');

// 0

todo = Ember.Object.create({ isDone: false });

todos.pushObject(todo);

App.todosController.get('remaining');

// 1

绑定

绑定是对两个属性建立一个连接,其中一个改变了另一个会自动的更新。绑定可以在相同的对象上连接属性,也可以贯穿两个不同的对象。与其他包含了某些绑定的实现的框架不同,Ember.js 的绑定可以用在任何对象,不只是视图和原型上。

 

一种最简单的创建双向绑定的方式是创建一个以Binding字符串结尾属性,然后指定一个全局范围的内容路径:

1

2

3

4

5

6

7

8

9

10

App.wife = Ember.Object.create({

  householdIncome: 80000

});

App.husband = Ember.Object.create({

  householdIncomeBinding: 'App.wife.householdIncome'

});

App.husband.get('householdIncome'); // 80000// Someone gets raise.

App.husband.set('householdIncome', 90000);

App.wife.get('householdIncome'); // 90000

要注意一下绑定没有立即更新。Ember会一直等待直到你应用程序的所有代码都运行完成才会同步所作的改变,所以你可以改变一个bound属性任意多次,不用担心同步绑定值时候的瞬态的开销。

单向绑定

单向绑定只朝着一个方向传播变化的。通常单向绑定只是为了性能优化,你可以安全地更多地使用简单的双向绑定语法(当然,如果你只改变一方面的变化那么双向绑定事实上就是单向绑定)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

App.user = Ember.Object.create({

  fullName: "Kara Gates"

});

App.userView = Ember.View.create({

  userNameBinding: Ember.Binding.oneWay('App.user.fullName')

});

// Changing the name of the user object changes// the value on the view.

App.user.set('fullName', "Krang Gates");

// App.userView.userName will become "Krang Gates"// ...but changes to the view don't make it back to// the object.

App.userView.set('userName', "Truckasaurus Gates");

App.user.get('fullName'); // "Krang Gates"

什么时候使用

有时候一个新的使用者会困扰于什么时候使用计算出的属性、绑定和监听器。以下是一些帮助指导:

 

使用计算出的属性是为了构建一个需要合并其他属性的新属性。计算出的属性不应该包含应用程序的行为,并且当他被调用的时候不应该引起任何副作用(除了在罕见的情况),对计算出的属性多次调用应总是保持相同的返回值(除了其依赖的属性发生了变化)

 

监听器应该包含反应其他属性变化的行为。监听器在一个绑定完成同步后你仍然需要执行一些行为的时候特别有用。

 

绑定经常被用来确保两个不同层对象的同步。例如:你使用Handlebars绑定你的视图到你的控制器。你可能经常绑定同一个层的对象。例如:你可以有一个App.selectedContactController绑定它的selectedContact属性到App.contactsController

创建一个命名空间

每个Ember应用应该有一个Ember.Application的实例。这个对象将作为全局访问你应用程序中所有的其他类和实例的命名空间服务。另外,它会设置页面的事件监听器,使得你的视图可以在用户与你的用户接口交互的时候接收到事件。

 

这里有个应用程序的例子:

 

window.App = Ember.Application.create();

你可以命名成你想要的任意名称。但是为了使绑定能够找到它,你必须以大写字母开头。

 

如果你嵌入一个Ember应用程序到一个已经存在的站点,你可以通过对已提供rootElement属性的指定来设置事件监听器:

1

2

3

window.App = Ember.Application.create({

  rootElement: '#sidebar'

});

 

使用Handlebars描述你的UI

Handlebars

Ember自带了Handlebars,一个语义话的模版语言。这些模版像是使用了嵌入表达式的有规律的HTML

 

你应该存储你的Handlebars模版到你应用程序的HTML文件中。在运行时,Ember将会编译这些模版,为此他们是在你的视图中是可使用的。

 

为了马上插入一个模版到你的文档,放置一个<script>标签到你的<body>标签中:

1

2

3

4

5

6

7

<html>

  <body>

    <script type="text/x-handlebars">

      Hello, <b>{{MyApp.name}}</b>

    </script>

  </body>

</html>

为了使模版在后面的使用中被用到,给<script>标签一个指定data-template-name属性:

1

2

3

4

5

6

7

<html>

  <head>

    <script type="text/x-handlebars" data-template-name="say-hello">

      Hello, <b>{{MyApp.name}}</b>

    </script>

  </head>

</html>

Ember.view

你可以使用Ember.view渲染一个Handlebars模版然后将其插入到DOM

 

为了告知视图要是用哪个模版,设置它的templateName属性。例如:你有一个这样的<script>标签:

1

2

3

4

5

6

7

<html>

  <head>

    <script type="text/x-handlebars" data-template-name="say-hello">

      Hello, <b>{{name}}</b>

    </script>

  </head>

</html>

我想设置templateName属性为'say-hello'

1

2

3

4

var view = Ember.View.create({

  templateName: 'say-hello',

  name: "Bob"

});

注意:在本向导的剩余部分,templateName属性将从大多数例子中被省略。你可以认为如果我们展示一个包含Ember.viewhandlebars模版的代码事例,视图已经为展示这个模版使用templateName属性进行了配置。

 

你可以通过调用appendTo追加视图到文档:

 

  view.appendTo('#container');

作为一个快捷方式,你可以调用append追加一个视图到文档的body

 

  view.append();

从文档删除一个视图,调用remove

 

  view.remove();

Handlerbars基础

正如你上面所看到的,你可以使用一个Handler的标记来包起你的属性来输出它的值,或者一些列的括号,像这样

 

My new car is {{color}}.

这会查找并打印视图的color属性。

 

例如:如果你的视图像这样:

1

2

3

 

App.CarView = Ember.View.extend({

  color: 'blue'

});

你的视图在浏览器中显示如下:

 

My new car is blue.

你也可以使用全局路径:

 

My new car is {{App.carController.color}}.

(Ember是通过检查首字母是否为大写来确定一个路径是全局的还是相对的,这就是为什么定义Ember应用程序的命名空间的名字必须以首字母大写开始的原因)

 

本指南中所有被描述的特性都是有意识绑定的。也就是说,如果你的模版中用到的值被改变了,那么HTML将被自动的更新。像有魔力似的。

 

当一个底层属性变化的时候,为了知道你HTML的哪个部分要被更新,Handlebars将插入一个带有独一无二ID的标记元素。如果你的程序运行的时候你观察过,你可能会注意到这些额外的元素:

1

2

3

4

My new car is

<scriptid="metamorph-0-start"type="text/x-placeholder"]]]]></script>

blue

<scriptid="metamorph-0-end"type="text/x-placeholder"]]]]></script>.

因为为确保每个HTML标签在相同的块中,所有的Handlebars表达式被包装到这些标记中,所以你不能这样做:

1

2

<!-- Don't do it! -->

<div {{#if isUrgent}}class="urgent"{{/if}}>

如果你想避免从这些封装的标记中获取属性输出,使用unbound 助手:

 

My new car is {{unbound color}}.

你的输出将是一个自由的标签,但是要小心,因为这个输出不会被自动的更新。

 

 

My new car is blue.

{{#if}}, {{else}}, {{#unless}}

有时你只想在一个属性存在时显示模版的一部分。例如:我们有一个包含person(一个包含firstNamelastName字段的对象)属性的视图。

 

1

2

3

4

5

6

App.SayHelloView = Ember.View.extend({

  person: Ember.Object.create({

    firstName: "Joy",

    lastName: "Clojure"

  })

});

为了达到只有person对象存在的时候才会显示那部分视图的目的,我们可以使用{{#if}}助手来展现一个包含条件的块:

1

2

3

{{#if person}}

  Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!

{{/if}}

如果参数被计算为falseundefinednull[]Handlebars将不会展现块内容。

 

如果表达式的值为false,我们还想更改模版的展现,则使用{{else}}

1

2

3

4

5

{{#if person}}

  Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!

{{else}}

  Please log in.

{{/if}}

如果只想在值为falsy的时展现块内容,那么使用{{#unless}}

1

2

3

{{#unless hasPaid}}

  You owe: ${{total}}

{{/unless}}

{{#if}}{{#unless}}是块表达式的例子。他们可以在模版的一部分调用助手。块表达式除了他们在助手名字的前面包含一个#和需要一个闭合的表达式之外,看起来像普通的表达式一样。

{{#with}}

有时你可能想要调用不同于当前Ember.view上下文的一部分模版。例如:我们可以使用{{#with}}助手来修改上面的代码:

1

2

3

{{#with person}}

  Welcome back, <b>{{firstName}} {{lastName}}</b>!

{{/with}}

{{#with}}将上下文改变成你传进去的那个。上下文是指属性被查找出来时,其被引用的对象。默认,上下文是属于相应的模版的Ember.view.

使用{{bindAttr}}绑定元素属性

除了文字之外,你可能还想你的模块来决定你的HMTL元素的属性。例如:一个包含URL的视图:

1

2

3

App.LogoView = Ember.View.extend({

  logoUrl: 'http://www.mycorp.com/images/logo.png'

});

Handlebars来展示这个图片最好的方式是这样的:

1

2

3

<div id="logo">

  <img {{bindAttr src="logoUrl"}} alt="Logo">

</div>

会生成如下HTML

1

2

3

<divid="logo"]]]]>

  <imgsrc="http://www.mycorp.com/images/logo.png"alt="Logo"]]]]></div>

如果你有个布尔值使用{{bindAttr}},它将会添加或删除指定的属性。例如,如下Ember视图:

1

2

3

App.InputView = Ember.View.extend({

  isDisabled: true

});

模版:

 

<input type="checkbox" {{bindAttr disabled="isDisabled"}}>

Handlebars将生成如下的HTML

 

<inputtype="checkbox"disabled]]]]>

使用{{bindAttr}}绑定类(css的类)名字

类属性可以像其他属性一样被绑定,但是它也有一些特殊的行为。默认的行为像你期待的那样:

1

2

3

4

App.AlertView = Ember.View.extend({

  priority: "p4",

  isUrgent: true

});

1

2

3

<div {{bindAttr class="priority"}}>

  Warning!

</div>

模版将会发表成:

1

2

3

<divclass="p4"]]]]>

  Warning!

</div>

如果你的绑定值是一个一个布尔,那么经过dasherize处理后的属性版本将会被作为一个Class来使用

 

1

2

3

<div {{bindAttr class="isUrgent"}}>

  Warning!

</div>

生成如下HTML

1

2

3

<divclass="is-urgent"]]]]>

  Warning!

</div>

和其他属性不同的是,你也可以绑定多个类:

1

2

3

<div {{bindAttr class="isUrgent priority"}}>

  Warning!

</div>

你也可以指定进行替换的类名字,来代替刚刚的dasherizing版本:

1

2

3

<div {{bindAttr class="isUrgent:urgent"}}>

  Warning!

</div>

这个例子中,如果属性isUrgent是真值,类urgent将会被添加。如果它是假值,那么类urgent将会被删除。

 

使用{{action}}处理事件

使用{{action}}助手来附加你的视图类的一个元素的事件被触发时的一个处理。

 

为当前视图附加一个元素的单击事件到编辑操作:

 

<a href="#" {{action "edit" on="click"}}>Edit</a>

默认的事件是单击,所以可以被简单的写成:

 

<a href="#" {{action "edit"}}>Edit</a>

包含{{action}}助手的视图作为默认的目标,也可以指向其他的视图:

 

<a href="#" {{action "edit" target="parentView"}}>Edit</a>

事件处理器可以随意接受一个jQuery的事件对象,它将会被扩展到包含的视图和上下文属性。这些属性会在将你的事件指向不同的视图时有用,例如:

1

2

3

4

5

6

App.ListingView = Ember.View.extend({

  templateName: 'listing',

  edit: function(event) {

    event.view.set('isEditing', true);

  }

});

上面讨论的任意一个视图会生成的如下HTML元素:

 

<ahref="#"data-ember-action="3"]]]]>Edit</a>

Ember将会基于内部分配的’data-ember-action id‘委托你指定的事件到你的目标视图处理器。

构建层级视图

到目前为止,我们讨论了为单一视图书写模版。然而,随着你的应用程序的增长,你经常会在页面的不同地方创建一个有层次的视图。每个视图在处理事件上都是可靠的,并且会维护你需要展示的属性。

{{view}}

使用{{view}}助手添加一个子视图到父亲,将会把一个路径带到视图类。

1

2

3

4

5

6

7

8

9

10

11

12

// Define parent view

App.UserView = Ember.View.extend({

  templateName: 'user',

  firstName: "Albert",

  lastName: "Hofmann"

});

// Define child view

App.InfoView = Ember.View.extend({

  templateName: 'info',

  posts: 25,

  hobbies: "Riding bicycles"

});

1

2

User: {{firstName}} {{lastName}}

{{view App.InfoView}}

1

2

3

<b>Posts:</b> {{posts}}

<br>

<b>Hobbies:</b> {{hobbies}}

如果我们创建App.UserView的实例并且渲染它,将会得到一个这样的DOM展现:

1

2

3

4

5

6

User: Albert Hofmann

<div>

  <b>Posts:</b> 25

  <br>

  <b>Hobbies:</b> Riding bicycles

</div>

相对路径

 

并非一定要用绝对路径,你也可以指定相对于父视图的相对路径。例如:我们可以像这样内嵌上面的视图层:

1

2

3

4

5

6

7

8

9

10

App.UserView = Ember.View.extend({

  templateName: 'user',

  firstName: "Albert",

  lastName: "Hofmann",

  infoView: Ember.View.extend({

    templateName: 'info',

    posts: 25,

    hobbies: "Riding bicycles"

  })

});

1

2

User: {{firstName}} {{lastName}}

{{view infoView}}

这样内嵌视图类的时候要确保使用小写字母,因为Ember将会把一个大写字母开头的属性解释为全局属性。

设置子视图模版

如果你想使用内联方式指定你的子视图模版,可以使用{{view}}助手的块结构。我们像这样重写上面的例子:

1

2

3

4

5

6

7

8

9

App.UserView = Ember.View.extend({

  templateName: 'user',

  firstName: "Albert",

  lastName: "Hofmann"

});

App.InfoView = Ember.View.extend({

  posts: 25,

  hobbies: "Riding bicycles"

});

1

2

3

4

5

6

User: {{firstName}} {{lastName}}

{{#view App.InfoView}}

  <b>Posts:</b> {{posts}}

  <br>

  <b>Hobbies:</b> {{hobbies}}

{{/view}}

把它作为赋值视图的部分页面时可能会有用。它允许你对页面上刚才的那部分的事件进行封装。

设置绑定

到目前为止的所有例子,我们都是直接在视图上设置静态的值。但是对于MVC架构最好的实现,事实上我们应该绑定我们的视图属性到控制器层。

 

让我们设置一个控制器来展现我们的用户数据:

1

2

3

4

5

6

7

8

App.userController = Ember.Object.create({

  content: Ember.Object.create({

    firstName: "Albert",

    lastName: "Hofmann",

    posts: 25,

    hobbies: "Riding bicycles"

  })

});

现在我们修改App.UserView为绑定到App.userController

1

2

3

4

5

App.UserView = Ember.View.extend({

  templateName: 'user',

  firstNameBinding: 'App.userController.content.firstName',

  lastNameBinding: 'App.userController.content.lastName'

});

尽当我们有很少的绑定要配置的时候,像App.UserView似的,直接在模版中声明这些绑定才有用。你可以通过附加参数到{{#view}}助手。如果你要做的只是配置绑定,那么通常是创建一个新的子类而别无其他的方法。

 

1

2

3

4

5

6

7

User: {{firstName}} {{lastName}}

{{#view App.UserView postsBinding="App.userController.content.posts"

        hobbiesBinding="App.userController.content.hobbies"}}

  <b>Posts:</b> {{posts}}

  <br>

  <b>Hobbies:</b> {{hobbies}}

{{/view}}

注意:事实上你可以把任何属性作为一个参数传给{{view}},而不仅仅是要绑定的。然而,一般来说如果你做了任何除了绑定的事情,创建一个子类是一个好主意。

修改视图的HTML

当你追加一个视图的时候,会保留它的内容创建一个新的HTML元素。如果你的视图没有任何子视图,他们也会作为父级HTML元素的孩子节点进行展示。

 

默认:Ember.View的实例创建一个<div>元素。你可以通过使用tagName参数来覆盖:

 

{{view App.InfoView tagName="span"}}

你也可以通过一个ID参数来赋值一个ID属性到视图的HTML元素。

 

{{view App.InfoView id="info-view"}}

这样就会很容易的使用CSSID选择器来设置样式:

1

2

3

4

/** Give the view a red background. **/

  #info-view {

    background-color: red;

  }

你同样可以赋值class的名称:

 

{{view App.InfoView class="info urgent"}}

你可以使用ClassBing来绑定类名称到一个视图的属性,而不是使用class。同样的行为在bindAttr的应用中进行了描述:

1

2

3

4

App.AlertView = Ember.View.extend({

  priority: "p4",

  isUrgent: true

});

 

{{view App.AlertView classBinding="isUrgent priority"}}

这个视图包装器的产出结果是这样:

 

<divid="sc420"class="sc-view is-urgent p4"]]]]></div>

显示列表元素

如果你想迭代一个列表的所有对象,可以使用Handlebars{{#each}}助手:

1

2

3

4

App.PeopleView = Ember.View.extend({

  people: [ { name: 'Yehuda' },

            { name: 'Tom' } ]

});

1

2

3

4

5

<ul>

  {{#each people}}

    <li>Hello, {{name}}!</li>

  {{/each}}

</ul>

将会输出一个list

1

2

3

4

<ul>

  <li>Hello, Yehuda!</li>

  <li>Hello, Tom!</li></ul>

如果你想为列表中的每个元素都创建一个视图,你可以绑定视图的一个属性到当前上下文。例如,这个例子为每个元素创建了一个视图并且使用content属性设置它们:

1

2

3

4

5

{{#each App.peopleController}}

  {{#view App.PersonView contentBinding="this"}}

    {{content.firstName}} {{content.lastName}}

  {{/view}}

{{/each}}

书写自定义助手:

有时,你可能会在你的应用程序里面多次使用一段相同的HTML。这种情况下,你可以注册一个自定义的助手,它可以在被任何模版调用。

 

举个例子,你经常会使用带有自定义类的<span>标签包装某些值。你可以像这样在JS中注册一个助手:

1

2

3

4

Handlebars.registerHelper('highlight', function(property) {

  var value = Ember.getPath(this, property);

  returnnew Handlebars.SafeString('<span class="highlight">'+value+'</span>');

});

如果想要从助手返回的HTML而不做任何转义,确保返回一个新的SafeString

 

Handlebar模版的任何地方,你都可以调用这个助手:

 

{{highlight name}}

它会输出以下内容:

 

<spanclass="highlight"]]]]>Peter</span>

注意:助手函数中传递的参数作为名字,而不是它们持有的值。这允许你在值上随意设置监听器。想要取得当前参数的值,你就要像上面展示的那样使用Ember.getPath.

视图包含的控件

Ember自带了预包装的构建基本控件的视图集,内容输入框、复选框和选择列表等。

EMBER.CHECKBOX

 

1

2

3

4

    <label>

      {{view Ember.Checkbox checkedBinding="content.isDone"}}

      {{content.title}}

    </label>

EMBER.TEXTFIELD 

1

2

3

4

5

6

    App.myText = Ember.TextField.extend({

        formBlurredBinding: 'App.adminController.formBlurred',

        change: function(evt) {

          this.set('formBlurred', true);

        }

      });

EMBER.SELECT

1

2

3

4

5

6

    {{view Ember.Select viewName="select"

                          contentBinding="App.peopleController"

                          optionLabelPath="content.fullName"

                          optionValuePath="content.id"

                          prompt="Pick a person:"

                          selectionBinding="App.selectedPersonController.person"}}

EMBER.TEXTAREA

1

2

3

    var textArea = Ember.TextArea.create({

            valueBinding: 'TestObject.value'

            });

如果你想添加这些控件中的任何一个到你的视图,那么你最好继承这些控件。

 

例如:

1

2

3

4

5

6

App.myText = Ember.TextField.extend({

    formBlurredBinding: 'App.adminController.formBlurred',

    change: function(evt) {

      this.set('formBlurred', true);

    }

  });

然后你可以把它作为子视图来用,也可以捕捉事件。在下面的例子中,名称为Name的输入框的变化将会使表单失去焦点,然后出现保存按钮。

1

2

3

4

5

6

7

8

9

10

11

12

<script id="formDetail" data-template-name='formDetail' type="text/x-handlebars">

    <form>

        <fieldset>

           <legend>Info:</legend>                

                   {{view App.myText name="Name" id="Name"  valueBinding="myObj.Name"}}

                   <label for="Name">Name</label><br/>

                   {{#if formBlurred}}

                    <a href="#" {{action "syncData" on="click"}}>Save</a>

                    {{/if}}

        </fieldset>

    </form>

</script>

 

深入视图

现在你已经很熟练的使用Handlebars,让我们更深入怎么处理事件和定制所需视图。

处理事件

不用必须在你想要回应的元素上注册事件监听器,仅仅在实现一个响应这个事件的视图即可。

 

例如,我们有一个这样的模版:

1

2

3

{{#view App.ClickableView}}

This is a clickable area!

{{/view}}

我们这样实现App.ClickableView,当它被单击的时候,一个alert被显示:

1

2

3

4

5

App.ClickableView = Ember.View.extend({

  click: function(evt) {

    alert("ClickableView was clicked!");

  }

});

事件会从目标视图连续冒泡到父视图,一直到根视图。这些值是只读的。如果你想使用JS人工管理视图(不使用Handlebars{{#view}}助手来创建视图),那么接着看下面的Ember.ContainerView文档。

使用Ember.ContainerView人工管理视图

通常,视图使用{{#view}}创建他们的子视图。有时使用人工管理一个视图的子视图也是有用的。如果你创建了Ember.ContainerView的实例,子视图数组就是可编辑的。你添加就会渲染到页面上,删除视图就会把它从DOM节点删除。

1

2

3

4

5

var container = Ember.ContainerView.create();

container.append();

var coolView = App.CoolView.create(),

    childViews = container.get('childViews');

childViews.pushObject(coolView);

作为一种快捷方式,你可以指定childViews作为属性,也可以把子视图们都作为键。当视图容器被创建后,这些视图将被实例化并且添加到子视图数组:

1

2

3

4

5

var container = Ember.ContainerView.create({

  childViews: ['firstView', 'secondView'],

  firstView: App.FirstView,

  secondView: App.SecondView

});

渲染管道

在你的视图变成DOM元素之前,它们首先表现为字符串。视图展现时会顺序将他们的子视图变成字符串,然后拼接在一起。

 

如果你想使用除了Handlebar以外的东西,那么你可以覆盖视图的render方法来来生成一个自定义HTML字符串。

1

2

3

App.MyView = Ember.View.extend({

  tagName: 'span'

});

这使得它很容易支持除了Handlebars以外的模版引擎。

 

不过要注意,如果你覆盖渲染,值并不会自动更新。任何的更新都会是你要做的。

定制HTML元素

一个视图在页面上代表一个DOM元素。你可以通过改变TagName属性来改变元素的类型。

1

2

3

App.MyView = Ember.View.extend({

  tagName: 'span'

});

你也可以通过设置它的classNames为一个字符串数组来指定要应用到视图的类名字。

1

2

3

App.MyView = Ember.View.extend({

  classNames: ['my-view']

});

如果你想根据视图上属性的状态来确定class的名字,可以使用绑定类名字。如果绑定的属性是一个Boolean属性,类名字将会根据值或添加或删除属性。

1

2

3

4

App.MyView = Ember.View.extend({

  classNameBindings: ['isUrgent'],

  isUrgent: true

});

生成以下视图:

 

<divclass="ember-view is-urgent">

如果isUrgent改变为false,那么is-urgent的类名字将会被删除。

 

默认Boolean属性的名字是dasherized。你可以使用冒号作为分界符自定义类名字。

1

2

3

4

App.MyView = Ember.View.extend({

  classNameBindings: ['isUrgent:urgent'],

  isUrgent: true

});

生成以下HTML

 

<divclass="ember-view urgent">

如果被限制的值是一个字符串,那么它就原封不动被追加到类的名字中。

视图上的属性绑定

可以在展现视图的时候使用attributeBindingsDOM元素绑定属性。

1

2

3

4

5

App.MyView = Ember.View.extend({

  tagName: 'a',

  attributeBindings: ['href'],

  href: "http://emberjs.com"

});

Ember的可枚举的API

什么是可枚举的

Ember中,可以是一个包含一组子对象的任何对象,允许你在这些子对象上使用可枚举的接口。最基本的可枚举对象是JS内建的Array

举个例子来说,所有的可枚举对象都支持标准的forEach方法。

1

2

3

[1,2,3].forEach(function(item) {

  console.log(item);

});

通常来说,枚举方法,例如forEach,会有一个附加的第二参数,它将成为回调函数中this的值(译者添加:和上下文的作用差不多)

1

2

3

4

var array = [1,2,3];

array.forEach(function(item) {

  console.log(item, this.indexOf(item));

}, array)

众多原因之中,你将会发现当使用另外一个可枚举方法作为回调给forEach的时候它会有用:

1

2

var array = [1,2,3];

array.forEach(array.removeObject, array);

注意:用这个方式来使用第二个参数有助于解决JS中使用this的值设置给window的限制。

Ember中可枚举的

通常,展现成列表的Ember对象实现可枚举接口。一些例子:

 

ArrayEmber用可枚举接口扩展了JS的原生数组。

ArrayProxy:一个包装了原生数组并且为视图层添加了额外的功能。

Set:一个能快速响应它是否包含了某一对象的对象。

可枚举接口

参数:

 

可枚举方法的回调函数包含三个参数:

item:当前迭代的元素。

index:一个整数,从0开始累加。

self:枚举器本身。

 

枚举一个可枚举对象的所有值使用forEach方法:

1

2

3

enumerable.forEach(function(item, index, self) {

  console.log(item);

});

调用枚举对象的每个元素的一些方法,使用invoke方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Person = Ember.Object.extend({

  sayHello: function() {

    console.log("Hello from " + this.get('name'));

  }

});

var people = [

  Person.create({ name: "Juan" }),

  Person.create({ name: "Charles" }),

  Person.create({ name: "Majd" })

]

people.invoke('sayHello');

// Hello from Juan// Hello from Charles// Hello from Majd

第一个和最后一个

 

你可以使用get('firstObject')get('lastObject')来取得第一个或最后一个元素。

1

2

[1,2,3].get('firstObject') // 1

[1,2,3].get('lastObject')  // 3

转换为数组

这很简单,将一个枚举对象转换成一个数组只需要调用它的toArray方法即可。

转换

你可以使用map方法转换一个可枚举对象为一个衍生数组:

1

2

3

4

['Goodbye', 'cruel', 'world'].map(function(item, index, self) {

  return item + "!";

});

// returns ["Goodbye!", "cruel!", "world!"]

每个对象的设值器和取值器

在使用forEachmap时经常会取得或者设置每个元素的一个属性。你可以使用getEach或者setEach来做。

1

2

3

4

var arr = [Ember.Object.create(), Ember.Object.create()];

// we now have an Array containing two Ember.Objects

arr.setEach('name', 'unknown');

arr.getEach('name') // ['unknown', 'unknown']

过滤

另外一个可枚举对象经常执行的任务是把枚举对象作为输入,基于一些条件对它进行过滤,然后返回一个新数组

 

对于任意的过滤,使用filter方法。filter方法期望如果想在最终的数组中包含它则在回调中返回真值,不希望包含则返回假值。

1

2

3

4

5

var arr = [1,2,3,4,5];

arr.filter(function(item, index, self) {

  if (item < 4) { returntrue; }

})

// returns [1,2,3]

和一个Ember对象集合进行协作的时候,你经常想基于一些属性过滤一个对象集。filterProperty方法是一个快捷方式。

1

2

3

4

5

6

7

8

9

10

Todo = Ember.Object.extend({

  title: null,

  isDone: false

});

todos = [

  Todo.create({ title: 'Write code', isDone: true }),

  Todo.create({ title: 'Go to sleep' })

];

todos.filterProperty('isDone', true);

// returns an Array containing just the first item

如果你只想返回第一个匹配值,而不是所有的值,使用findProperty,它就像你使用了filterfilterProperty,但是只返回了一个元素。

汇总信息 (all any)

如果你想找出可枚举对象中的每个元素是否都匹配一些条件,可以使用every方法。

1

2

3

4

5

6

7

8

9

10

11

12

Person = Ember.Object.extend({

  name: null,

  isHappy: false

});

var people = [

  Person.create({ name: 'Yehuda', isHappy: true }),

  Person.create({ name: 'Majd', isHappy: false })

];

people.every(function(person, index, self) {

  if(person.get('isHappy')) { returntrue; }

});

// returns false

如果你想找出可枚举对象中的至少有一个元素是否都匹配一些条件,可以使用some方法。

1

2

3

4

people.some(function(person, index, self) {

  if(person.get('isHappy')) { returntrue; }

});

// returns true

就像filter方法一样,everysome方法有类似的everyPropertysomeProperty方法。

1

2

people.everyProperty('isHappy', true) // false

people.someProperty('isHappy', true)  // true

 

分享到:
评论

相关推荐

    ember-tml:Ember插件,用于使用Translation Exchange中的TML(翻译标记语言)进行高级本地化

    此插件添加了一些帮助程序,用于通过Translation Exchange使用翻译标记语言(TML)对余烬应用程序进行高级本地化。 翻译标记语言(TML)是一种简单的标记语言,提供用于标识字符串中的动态数据和修饰的语法。 TML...

    ember-i18next:将i18next集成到Ember CLI应用程序中

    ember-i18next 关于 一个插件,用于使用库国际化Ember.js应用程序。 该插件提供了一个包装i18next的Ember服务以及一个用于在模板中显示本地化文本的Handlebars帮助器。 兼容性 ember-i18next支持当前的Ember(发行版...

    官方网站:巴西利亚·恩伯公社

    EmberéumatraduçãoemPortuguês做。 Fique por Dentro 一个科伦特traduçãoéiniciada POR。 葡萄牙人自愿志愿工作的结果。 Vocêconcorda que: Ao contribuir com作为traduções,请在GitHub上使用divulga...

    mdEditor:用于编写元数据的Web应用程序,一个ADIwg项目

    mdEditor 用于编写元数据的Web应用程序。 使用。 转到以使用该应用程序。 有关的信息,请参见 。 另外,请参阅以获取有关该项目的更多信息。 先决条件(用于开发) 您需要在计算机上正确安装以下物品。... ember te

    永磁同步电机发电给蓄电池充电控制仿真模型解析 - PMSG与双闭环控制技术

    内容概要:本文详细介绍了永磁同步旋转电机(PMSG)发电给蓄电池充电的控制仿真模型。该模型主要由永磁同步发电机、三相整流桥、整流桥控制模块、测量模块和蓄电池组成。文中首先解释了各组件的功能及其相互协作方式,接着重点讨论了整流桥控制模块的转速、电流双闭环控制机制,尤其是PI控制器的应用。此外,还探讨了储能管理和系统性能优化的方法,如通过LC滤波、自适应偏置、在线参数辨识等手段提高系统的稳定性和效率。最后,通过对实际波形的分析展示了系统的优异表现。 适合人群:从事电力系统、新能源领域的研究人员和技术人员,以及对电机控制感兴趣的工程专业学生。 使用场景及目标:适用于研究和开发高效的新能源发电与储能系统,旨在提升发电效率、稳定性和可靠性。具体应用场景包括但不限于风电场、太阳能电站、电动汽车充电站等。 其他说明:文中提供的代码片段和参数配置均为简化版本,实际应用中需根据具体情况进一步调整优化。

    餐饮业人才流失现状分析及对策研究.doc

    餐饮业人才流失现状分析及对策研究

    车辆动力学领域LQR/LQG控制的主动悬架模型研究及其MATLAB/Simulink实现

    内容概要:本文详细探讨了LQR(线性二次调节器)和LQG(线性二次高斯)控制在车辆主动悬架系统中的应用。文章首先介绍了LQR控制的基本原理,即通过状态反馈控制使系统达到最优状态。接着,通过Simulink建立了多种自由度的主动悬架模型(2自由度、4自由度和7自由度),并在MATLAB中实现了相应的控制算法。文中展示了不同自由度模型的关键性能指标对比,如悬架动挠度、簧载质量加速度等,并提供了具体的MATLAB代码示例。此外,文章还讨论了LQG控制中卡尔曼滤波的应用,以及其在处理噪声环境中的优势。 适合人群:从事车辆工程、控制系统设计的研究人员和技术人员,尤其是对主动悬架系统感兴趣的读者。 使用场景及目标:适用于希望深入了解LQR/LQG控制理论及其在车辆主动悬架系统中具体应用的人群。目标是帮助读者掌握如何利用MATLAB/Simulink搭建和优化主动悬架模型,从而提高车辆行驶的舒适性和稳定性。 其他说明:文章不仅提供了理论解释,还包括大量实用的代码片段和图表,便于读者理解和实践。特别强调了在不同自由度模型之间的选择依据,以及LQG控制在实际应用场景中的重要性。

    离职交接表.doc

    离职交接表.doc

    计算机课程设计相关资源

    计算机课程设计相关资源

    MATLAB中滚动轴承二自由度动力学建模与故障动态响应仿真

    内容概要:本文详细介绍了如何使用MATLAB进行滚动轴承的二自由度动力学建模,涵盖正常状态及内外圈、滚动体故障的动态响应仿真。首先建立了二自由度的动力学方程,定义了质量、阻尼和刚度矩阵,并根据不同类型的故障(内圈、外圈、滚动体)设置了相应的故障激励力。通过ODE求解器(如ode45)求解微分方程,得到时域内的振动波形。接着进行了频谱分析,展示了不同状态下频谱图的特点,如内圈故障在转频的倍频处出现峰值,外圈故障在较低频段有特征峰,滚动体故障表现为宽频带特性。此外,还提供了故障特征提取的方法,如包络谱分析。 适用人群:机械工程领域的研究人员和技术人员,特别是从事机械设备故障诊断和预测性维护的专业人士。 使用场景及目标:适用于需要理解和研究滚动轴承在不同工况下的动态行为的研究项目。主要目标是帮助用户掌握如何利用MATLAB进行轴承动力学建模,识别并分析各种故障模式,从而提高设备的可靠性和安全性。 其他说明:文中提供的代码可以直接用于实验验证,同时给出了许多实用的提示和注意事项,如选择合适的ODE求解器、合理设置故障幅值以及避免数值发散等问题。

    低通滤波器:滤波算法及其在传感器数据处理中的应用

    内容概要:本文详细介绍了低通滤波器的基本概念、不同类型的滤波算法以及它们的应用场景。首先解释了简单的移动平均滤波,这是一种常用且易实现的方法,适用于快速去除高频噪声。接着深入探讨了一阶RC低通滤波器的工作原理和实现方式,强调了alpha系数的选择对滤波效果的影响。此外,还提到了基于环形缓冲区的实时滤波技术和更高阶的巴特沃斯滤波器,后者提供了更好的频率选择性和稳定性。文中通过多个实例展示了如何根据具体的传感器数据特点选择合适的滤波算法,并给出了相应的Python代码片段用于演示和验证。 适合人群:从事嵌入式系统开发、传感器数据分析及相关领域的工程师和技术爱好者。 使用场景及目标:帮助开发者理解和掌握不同类型低通滤波器的特点与实现方法,以便更好地应用于实际项目中,如处理陀螺仪、温度传感器、心率传感器等设备的数据,提高信号质量和系统的可靠性。 其他说明:文章不仅提供了理论知识,还包括了许多实用技巧和注意事项,如滤波器参数的选择、初始化处理、采样率稳定性等问题,这些都是确保滤波效果的关键因素。同时,附带的代码示例可以帮助读者更快地上手实践。

    基于自抗扰控制(ADRC)的永磁同步电机(PMSM)矢量控制技术及其实现

    内容概要:本文深入探讨了基于自抗扰控制(ADRC)的永磁同步电机(PMSM)矢量控制技术。首先介绍了PMSM的特点及其广泛应用背景,强调了矢量控制在实现电机高性能控制方面的重要性。针对传统矢量控制存在的不足,引入了ADRC这一新型控制策略,详细解释了ADRC的工作原理,包括跟踪微分器(TD)、扩张状态观测器(ESO)和非线性状态误差反馈控制律(NLSEF)三个组成部分的功能。随后展示了如何将ADRC应用于PMSM的电流环和速度环控制中,并提供了具体的Python代码实现示例。实验结果显示,在面对负载变化等扰动情况下,采用ADRC的控制系统表现出更好的稳定性和平滑性。 适用人群:从事电机控制领域的研究人员和技术人员,特别是那些希望深入了解并掌握先进控制算法的人群。 使用场景及目标:适用于需要提高永磁同步电机控制系统鲁棒性和响应速度的应用场合,如工业自动化设备、电动汽车等领域。目标是帮助读者理解ADRC的基本概念及其在PMSM矢量控制中的具体应用,从而能够在实际项目中实施该技术。 其他说明:文中还讨论了一些实用技巧,如参数调整的方法和注意事项,以及与其他控制方法(如PI控制)的性能对比。此外,作者鼓励读者尝试不同的参数配置以找到最适合特定应用场景的最佳设置。

    外贸公司员工离职流程及工作交接程序.xls

    外贸公司员工离职流程及工作交接程序.xls

    基于博途1200PLC的教学楼打铃控制系统:数码管显示与定时打铃的实现

    内容概要:本文详细介绍了基于西门子S7-1200 PLC的教学楼打铃控制系统的设计与实现。硬件方面,采用4位7段共阳数码管直接连接PLC的DO点,通过中间继电器或晶体管输出型PLC确保电流足够。软件部分,使用SCL语言编写动态扫描程序,实现数码管的时间显示,并通过系统时钟和定时器实现精确的打铃控制。此外,文章还讨论了数码管显示调试中的常见问题及其解决方案,如鬼影消除、段码转换和时间同步等。 适合人群:具备PLC编程基础的技术人员,尤其是对工业自动化感兴趣的工程师。 使用场景及目标:适用于需要构建或维护教学楼打铃系统的学校和技术爱好者。目标是掌握PLC编程技巧,理解数码管显示和定时控制的工作原理,以及提高对硬件配置和调试的理解。 其他说明:文中提供了详细的代码片段和硬件配置建议,帮助读者更好地理解和实施该项目。同时,强调了项目中的挑战和解决方案,使读者能够避免常见的错误并优化系统性能。

    三菱PLC与显触摸屏实现定长送料系统的伺服/步进控制

    内容概要:本文详细介绍了如何利用三菱PLC(具体型号为FX5U-32MT)和显触摸屏构建定长送料控制系统。该系统支持伺服和步进电机两种驱动方式,涵盖了点动、相对定位和绝对定位三大核心功能。文中不仅提供了详细的硬件连接方法,还展示了具体的PLC梯形图编程实例,以及触摸屏界面的设计要点。特别强调了调试过程中可能遇到的问题及其解决方案,如电子齿轮比计算错误、绝对定位前的原点回归、急停信号的正确接入等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些对PLC编程和伺服/步进电机控制有一定基础的人群。 使用场景及目标:适用于需要精确控制物料长度的场合,如包装、切割等行业。通过该系统可以提高生产效率,减少人工干预,确保送料精度达到±0.02mm。此外,还可以帮助用户掌握PLC编程技巧,提升对伺服/步进电机的理解。 其他说明:文章中提到的一些关键技术点,如点动模式的手动微调、绝对定位的坐标系建立、相对定位的连续作业优化等,对于理解和实施类似的自动化项目非常有帮助。同时,作者分享了许多宝贵的实践经验,有助于读者避开常见陷阱并顺利完成项目部署。

    信号处理领域中基于EMD及其改进方法的信号降噪与性能评估

    内容概要:本文详细介绍了如何利用经验模态分解(EMD)及其两种改进方法——集合经验模态分解(EEMD)和互补集合经验模态分解(CEEMDAN),来进行信号降噪。首先构建了一个由多个正弦波组成的混合信号并加入高斯噪声,随后使用三种方法对该带噪信号进行了分解,通过相关系数筛选有效的固有模态函数(IMF),最终重构信号并评估降噪效果。文中提供了详细的Python代码实现,包括信号生成、分解、重构以及性能评估的具体步骤。性能评估主要采用信噪比(SNR)和均方误差(MSE)作为衡量标准,结果显示CEEMDAN在降噪方面表现出色。 适合人群:从事信号处理领域的研究人员和技术人员,尤其是那些希望深入了解EMD系列算法及其应用的人群。 使用场景及目标:适用于需要对含噪信号进行预处理的各种应用场景,如机械故障诊断、生物医学工程等领域。目标是提高信号的质量,从而更好地支持后续的数据分析和决策制定。 其他说明:文中不仅提供了完整的代码实现,还讨论了不同参数的选择对降噪效果的影响,强调了实际应用中需要注意的问题,如计算资源限制、信号特性的考虑等。此外,作者鼓励读者尝试将仿真信号替换为实际数据,以便更好地理解和掌握这些方法的应用技巧。

    医学图像分割数据集:眼底血管图像语义分割数据集(约48张数据和标签)

    医学图像分割数据集:眼底血管图像语义分割数据集(约48张数据和标签) 【2类别的分割】:背景:0,1:眼底血管(具体参考classes文件) 数据集介绍:【已经划分好】 训练集:images图片目录+masks模板目录,34张左右图片和对应的mask图片 验证集:images图片目录+masks模板目录,10张左右图片和对应的mask图片 测试集:images图片目录+masks模板目录,4张左右图片和对应的mask图片 除此之外,包含一个图像分割的可视化脚本,随机提取一张图片,将其原始图片、GT图像、GT在原图蒙板的图像展示,并保存在当前目录下 医学图像分割网络介绍:https://blog.csdn.net/qq_44886601/category_12102735.html 更多图像分割网络unet、swinUnet、trasnUnet改进,参考改进专栏:https://blog.csdn.net/qq_44886601/category_12803200.html

    汽车工程中MATLAB/Simulink实现电动助力转向(EPS)系统的企业级量产模型

    内容概要:本文详细介绍了如何利用MATLAB和Simulink构建并优化电动助力转向(EPS)系统的企业级量产模型。首先探讨了随速助力曲线的设计,展示了如何通过车速和手力矩传感器输入计算助力扭矩。接着深入讲解了Simulink ASW(应用软件层)子系统的具体实现,包括移动平均滤波、助力特性模块、状态机设计以及回正控制等关键技术环节。文中还特别强调了处理现实世界非线性的挑战,如温度补偿、摩擦补偿和故障诊断方法。此外,讨论了手力闭环控制、PID调节、状态机设计以及摩擦模型简化等方面的技术细节,并提到了模型在环测试(MIL)、硬件在环测试(HIL)等验证手段。 适合人群:从事汽车电子控制系统开发的研究人员和技术工程师,尤其是对电动助力转向系统感兴趣的开发者。 使用场景及目标:适用于希望深入了解EPS系统内部工作原理及其优化方法的专业人士。主要目标是帮助读者掌握如何使用MATLAB/Simulink搭建高效可靠的EPS模型,从而应用于实际产品开发中。 其他说明:文章不仅提供了理论知识,还包括了许多实用的代码片段和实践经验分享,有助于读者更好地理解和应用相关技术。

    51单片机光照强度检测系统的实现与优化:滑动变阻器模拟光敏电阻的应用

    内容概要:本文详细介绍了基于51单片机的光照强度检测系统的设计与实现。主要采用滑动变阻器模拟光敏电阻,通过ADC0804进行模数转换,最终在LCD显示屏上显示光照强度等级。文中不仅提供了详细的硬件连接方法,如滑动变阻器与ADC0804的连接、单片机控制ADC的启动和读数等,还包括了完整的C语言源代码,涵盖了ADC读取、数据处理、阈值判断以及Protues仿真的具体步骤。此外,作者还分享了一些实用的调试技巧,如使用_nop_()指令保证信号稳定、加入滤波算法提高数据准确性等。 适合人群:具有一定单片机基础知识的学习者、电子爱好者、初学者及希望深入了解ADC工作的工程师。 使用场景及目标:①帮助读者掌握51单片机与ADC的工作原理及其应用;②提供一种低成本、易操作的光照检测解决方案;③通过实例演示,让读者学会如何进行硬件连接、编写相关程序并解决常见问题。 其他说明:文章强调了硬件连接的注意事项,如ADC0804的CLK引脚接法、滑动变阻器的设置范围等,并给出了具体的代码实现,便于读者理解和实践。同时,还提到了一些优化措施,如加入抗干扰设计、改进数据处理算法等,进一步提升了系统的性能。

    基于Comsol的三轴试验数值模拟:D-C、D-P、M-C准则的应用与实现

    内容概要:本文详细介绍了如何利用Comsol软件结合邓肯张(D-C)、德鲁克普拉格(D-P)和摩尔库伦(M-C)准则进行三轴试验的数值模拟。首先简述了各准则的基本概念及其适用范围,接着逐步讲解了在Comsol中创建土样模型、设定材料属性、施加边界条件和载荷的具体步骤。随后,文章展示了求解过程及结果分析方法,强调了通过数值模拟生成应力-应变曲线并与实际试验数据对比的重要性。此外,文中还提供了许多实用技巧,如参数设置、加载步控制、网格划分等,帮助提高模拟精度和效率。 适合人群:从事岩土工程研究的技术人员、研究生及以上学历的研究人员。 使用场景及目标:适用于需要深入了解土体力学特性的科研工作者,旨在通过数值模拟辅助实际三轴试验,减少实验成本并提升研究深度。具体目标包括掌握不同准则的特点及应用场景,学会使用Comsol进行三轴试验建模与仿真,能够根据模拟结果优化试验设计。 其他说明:文章不仅涵盖了理论知识和技术细节,还分享了许多实践经验,有助于读者更好地理解和应用所学内容。

Global site tag (gtag.js) - Google Analytics