You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -849,7 +849,7 @@ Since Martin Fowler states that
849
849
`$resource` does not implements exactly the Active Record pattern, since it communicates with RESTful service instead of the database. Anyway, we can consider it as "Active Record like RESTful communication".
As stated above the scopes in an AngularJS application form a hierarchy known as the scope chain. Some of the scopes are "isolated", which means that they don't inherit prototypically by their parent scope, but are connected to it via their `$parent` property.
1232
1232
-->
@@ -1346,20 +1346,38 @@ We can think of the `watcher` object as a command. The expression of the command
>Page Controller pattern accept input from the page request, invoke the requested actions on the model, and determine the correct view to use for the resulting page. Separate the dispatching logic from any view-related code
Since there is a lot of duplicate behavior between the different pages (like rendering footers, headers, taking care of the user's session, etc.) page controllers can form a hierarchy. In AngularJS we have controllers, which are with more limited scope of responsibilities. They don't accept user requests, since this is responsibility of the `$route` or `$state` services and the page rendering is responsibility of the directives `ng-view`/`ui-view`.
Similarly to the page controllers, AngularJS controllers handle user interactions, provide and update the models. The model is exposed to the view when it is being attached to the scope, all methods invoked by the view, in result of user actions, are ones, which are already attached to the scope. Another similarity between the page controllers and the AngularJS controllers is the hierarchy, which they form. It corresponds to the scope hierarchy. That way common actions can be isolated to the base controllers.
1374
+
-->
1360
1375
1376
+
AngularJS 中的 controller 与 ASP.NET WebForms 背后的代码非常相似,它们有着几乎重合的功用。以下是控制器层级的例子:
1377
+
<!--
1361
1378
The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap.
1362
1379
Here is an example hierarchy between few controllers:
1380
+
-->
1363
1381
1364
1382
```HTML
1365
1383
<!doctype html>
@@ -1390,17 +1408,29 @@ function ChildCtrl($scope, User) {
This example aims to illustrates the most trivial way to reuse logic by using a base controller, anyway in production applications I don't recommend you to put your authorization logic in the controllers. The access to the different routes could be determined on a higher level of abstraction.
The `ChildCtrl` is responsible for handling actions such as clicking the button with label `"Click"` and exposing the model to the view, by attaching it to the scope.
This is actually not a design pattern from Gang of Four, neither one from P of EAA. This is a traditional JavaScript pattern, which main goal is to provide encapsulation and privacy.
Using the module pattern you can achieve privacy based on the JavaScript's functional lexical scope. Each module may have zero or more private members, which are hidden in the local scope of a function. This function returns an object, which exports the public API of the given module:
In the example above we have IIFE (Immediately-Invoked Function Expression), which after being called returns an object, with two methods (`setTitle` and `getTitle`). The returned object is being assigned to the `Page` variable.
Once we want to inject `foo` inside any other component we won't be able to use the private methods, but only the public ones. This solution is extremely powerful especially when one is building a reusable library.
>A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself.
根据以上表述,数据映射器是用来在持久化数据存储和内存中的数据表述之间进行双向数据传输。AngularJS 应用通常是与 API 服务器进行数据交流。此服务器是用某种服务器端语言 (Ruby、PHP、Java、JavaScript 等) 实现.
1505
+
<!--
1459
1506
As the description above states, the data mapper is used for bidirectional transfer of data between a persistent data store and an in memory data representation. Usually our AngularJS application communicates with API server, which is written in any server-side language (Ruby, PHP, Java, JavaScript, etc.).
1507
+
-->
1460
1508
1509
+
一般来说,如果服务器端提供 RESTful API,`$resource` 可以帮助我们以 Active Record 类的方式与服务器通讯。尽管在某些应用中,从服务器返回的数据并非是最适合于在前端使用的格式。
1510
+
<!--
1461
1511
Usually, if we have RESTful API `$resource` will help us communicate with the server in Active Record like fashion. Although, in some applications the data entities returned by the server are not in the most appropriate format, which we want to use in the front-end.
1512
+
-->
1462
1513
1514
+
例如,让我们假设某个应用中,每个用户包含:
1515
+
<!--
1463
1516
For instance, lets assume we have application in which each user has:
1517
+
-->
1464
1518
1465
1519
- name
1466
1520
- address
1467
1521
- list of friends
1468
1522
1523
+
并且 API 提供了一下方法:
1524
+
<!--
1469
1525
And our API has the methods:
1526
+
-->
1470
1527
1528
+
- `GET/user/:id` - 返回指定用户的用户名和地址
1529
+
- `GET/friends/:id` - 返回指定用户的好友列表
1530
+
<!--
1471
1531
- `GET/user/:id` - returns the user's name and the address of given user
1472
1532
- `GET/friends/:id` - returns the list of friends of given user
Possible solution is to have two different services, one for the first method and one for the second one. Probably more useful solution would be if we have a single service called `User`, which loads the user's friends when we request the user:
1538
+
-->
1475
1539
1476
1540
```javascript
1477
1541
app.factory('User', function ($q) {
@@ -1494,9 +1558,15 @@ app.factory('User', function ($q) {
1494
1558
});
1495
1559
```
1496
1560
1561
+
如此一来,我们就创建了一个伪数据映射器,用来使我们的 API 适应 SPA (单页应用程序) 的需求。
1562
+
<!--
1497
1563
This way we create pseudo-data mapper, which adapts our API according to the SPA requirements.
1564
+
-->
1498
1565
1566
+
我们可以以下方式使用 `User` 服务:
1567
+
<!--
1499
1568
We can use the `User` service by:
1569
+
-->
1500
1570
1501
1571
```javascript
1502
1572
functionMainCtrl($scope, User) {
@@ -1507,7 +1577,10 @@ function MainCtrl($scope, User) {
1507
1577
}
1508
1578
```
1509
1579
1580
+
以及如下模版片段:
1581
+
<!--
1510
1582
And the following partial:
1583
+
-->
1511
1584
1512
1585
```html
1513
1586
<div>
@@ -1526,17 +1599,26 @@ And the following partial:
1526
1599
</div>
1527
1600
```
1528
1601
1529
-
#### Observer Pattern as an External Service
1602
+
#### <a name='observer-pattern-as-an-external-service'>观察者模式作为外部服务 (Observer Pattern as an External Service)</a>
Below is an example taken from [here](https://github.com/greglbd/angular-observer-pattern). This is an angular factory which creates a service implementing the Observer Pattern. It works well with the ControllerAs method of working as it can be much more efficient that `$scope.$watch` and more specific to a unique scope or object than $emit and $broadcast when used correctly.
1609
+
-->
1534
1610
1611
+
**用例:**你可以使用此模式来在两个使用同一模型但互不关联的控制器之间通讯。
1612
+
<!--
1535
1613
**Use Case:** You would use this pattern to communicate between 2 controllers that use the same model but are not connected in anyway.
0 commit comments