From dca0111eb666c141ee45eceb32ea5062dbf64f84 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 19:30:06 +0900 Subject: [PATCH 01/27] Add README-ja-jp.md --- README-ja-jp.md | 1095 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1095 insertions(+) create mode 100644 README-ja-jp.md diff --git a/README-ja-jp.md b/README-ja-jp.md new file mode 100644 index 0000000..7f1ba55 --- /dev/null +++ b/README-ja-jp.md @@ -0,0 +1,1095 @@ +# AngularJS in Patterns + +_このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/angularjs-in-patterns/blob/master/README.md)の日本語翻訳版です。_ + + + +## 目次 + +* [要旨](#要旨) +* [はじめに](#はじめに) +* [AngularJS overview](#angularjs-overview) +* [Partials](#partials) +* [Controllers](#controllers) +* [Scope](#scope) +* [Directives](#directives) +* [Filters](#filters) +* [Services](#services) +* [AngularJS Patterns](#angularjs-patterns) +* [Services](#services-1) + * [Singleton](#singleton) + * [Factory Method](#factory-method) + * [Decorator](#decorator) + * [Facade](#facade) + * [Proxy](#proxy) + * [Active Record](#active-record) + * [Intercepting Filters](#intercepting-filters) +* [Directives](#directives-1) + * [Composite](#composite) + * [Interpreter](#interpreter) + * [Template View](#template-view) +* [Scope](#scope-1) + * [Observer](#observer) + * [Chain of Responsibilities](#chain-of-responsibilities) + * [Command](#command) +* [Controller](#controller-1) + * [Page Controller](#page-controller) +* [Others](#others) + * [Module Pattern](#module-pattern) + * [Data Mapper](#data-mapper) +* [References](#references) + + + +## Abstract + +One of the best ways to learn something new is to see how the things you already know are used in it. +This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. +The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application. + +## Introduction + +The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned. + +The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS. + +## AngularJS overview + +AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). +SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. +Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are: + +- two-way data binding +- dependency injection +- separation of concerns +- testability +- abstraction + +The separation of concerns is achieved by dividing each AngularJS application into separate components, such as: + +- partials +- controllers +- directives +- services +- filters + +These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic. + +### Partials + +The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example). + +Initially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework. + +**Sample partial** + +```HTML + + + + + + + + + +``` + +With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked. + +### Controllers + +The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*. + +```JavaScript +function MyController($scope) { + $scope.buttonText = 'Click me to change foo!'; + $scope.foo = 42; + + $scope.changeFoo = function () { + $scope.foo += 1; + alert('Foo changed'); + }; +} +``` + +For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways. + +1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding. +2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`. + +All the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones. + +### Scope + +In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial. + +Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype. + +Scope inheritance is illustrated in the following example: + +```HTML +
+
+ + +
+
+``` + +```JavaScript +function BaseCtrl($scope) { + $scope.foo = function () { + alert('Base foo'); + }; +} + +function ChildCtrl($scope) { + $scope.bar = function () { + alert('Child bar'); + }; +} +``` + +With `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`. + +### Directives + +In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new direcrive or consider refactoring of already existing one, which could handle the required DOM manipulations. +Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as: + +- template +- compile function +- link function +- etc... + +By citing the name of the directives they can be used inside the declarative partials. + +Example: + +```JavaScript +myModule.directive('alertButton', function () { + return { + template: '', + scope: { + content: '@' + }, + replace: true, + restrict: 'E', + transclude: true, + link: function (scope, el) { + el.click(function () { + alert(scope.content); + }); + } + }; +}); +``` + +```HTML +Click me +``` + +In the example above the tag `` will be replaced button element. When the user clicks on the button the string `42` will be alerted. + +Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here. + +### Filters + +The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection. + +Here is a definition of a sample filter, which changes the given string to uppercase: + +```JavaScript +myModule.filter('uppercase', function () { + return function (str) { + return (str || '').toUpperCase(); + }; +}); +``` + +Inside a partial this filter could be used using the Unix's piping syntax: + +```HTML +
{{ name | uppercase }}
+``` + +Inside a controller the filter could be used as follows: + +```JavaScript +function MyCtrl(uppercaseFilter) { + $scope.name = uppercaseFilter('foo'); //FOO +} +``` + +### Services + +Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service. + +```JavaScript +myModule.service('Developer', function () { + this.name = 'Foo'; + this.motherLanguage = 'JavaScript'; + this.live = function () { + while (true) { + this.code(); + } + }; +}); +``` + +The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives). + +```JavaScript +function MyCtrl(developer) { + var developer = new Developer(); + developer.live(); +} +``` + +## AngularJS Patterns + +In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. + +In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS. + +### Services + +#### Singleton + +>The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. + +In the UML diagram bellow is illustrated the singleton design pattern. + +![Singleton](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg "Fig. 1") + +When given dependency is required by any component, AngularJS resolves it using the following algorithm: + +- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility). +- If the dependency exists AngularJS pass it as parameter to the component, which requires it. +- If the dependency does not exists: + - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency. + - AngularJS caches it inside the hash map mentioned above. + - AngularJS passes it as parameter to the component, which requires it. + +We can take better look at the AngularJS' source code, which implements the method `getService`: + +```JavaScript +function getService(serviceName) { + if (cache.hasOwnProperty(serviceName)) { + if (cache[serviceName] === INSTANTIATING) { + throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- ')); + } + return cache[serviceName]; + } else { + try { + path.unshift(serviceName); + cache[serviceName] = INSTANTIATING; + return cache[serviceName] = factory(serviceName); + } catch (err) { + if (cache[serviceName] === INSTANTIATING) { + delete cache[serviceName]; + } + throw err; + } finally { + path.shift(); + } + } +} +``` + +We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`). + +This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation: + +- It improves the testability of your source code +- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy) + +For further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered. + +#### Factory Method + +>The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. + +![Factory Method](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg "Fig. 2") + +Lets consider the following snippet: + +```JavaScript +myModule.config(function ($provide) { + $provide.provider('foo', function () { + var baz = 42; + return { + //Factory method + $get: function (bar) { + var baz = bar.baz(); + return { + baz: baz + }; + } + }; + }); +}); + +``` + +In the code above we use the `config` callback in order to define new "provider". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way. + +Each service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance. + +We can dig a little bit deeper in AngularJS' implementation: + +```JavaScript +//... + +createInternalInjector(instanceCache, function(servicename) { + var provider = providerInjector.get(servicename + providerSuffix); + return instanceInjector.invoke(provider.$get, provider, undefined, servicename); +}, strictDi)); + +//... + +function invoke(fn, self, locals, serviceName){ + if (typeof locals === 'string') { + serviceName = locals; + locals = null; + } + + var args = [], + $inject = annotate(fn, strictDi, serviceName), + length, i, + key; + + for(i = 0, length = $inject.length; i < length; i++) { + key = $inject[i]; + if (typeof key !== 'string') { + throw $injectorMinErr('itkn', + 'Incorrect injection token! Expected service name as string, got {0}', key); + } + args.push( + locals && locals.hasOwnProperty(key) + ? locals[key] + : getService(key) + ); + } + if (!fn.$inject) { + // this means that we must be an array. + fn = fn[length]; + } + + return fn.apply(self, args); +} +``` + +From the example above we can notice how the `$get` method is actually used: + +```JavaScript +instanceInjector.invoke(provider.$get, provider, undefined, servicename) +``` + +The snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`. + +If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product". + +There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like: + +- The most appropriate moment, when the component needs to be instantiated +- Resolving all the dependencies required by the component +- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers) + +#### Decorator + +>The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. + +![Decorator](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg "Fig. 4") + +AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create "wrapper" of any service you have previously defined or used by a third-party: + +```JavaScript +myModule.controller('MainCtrl', function (foo) { + foo.bar(); +}); + +myModule.factory('foo', function () { + return { + bar: function () { + console.log('I\'m bar'); + }, + baz: function () { + console.log('I\'m baz'); + } + }; +}); + +myModule.config(function ($provide) { + $provide.decorator('foo', function ($delegate) { + var barBackup = $delegate.bar; + $delegate.bar = function () { + console.log('Decorated'); + barBackup.apply($delegate, arguments); + }; + return $delegate; + }); +}); +``` +The example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `"foo"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. +We decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context. + +Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop). + +#### Facade + +>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: + +>1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; + +>2. make the library more readable, for the same reason; + +>3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; + +>4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). + +![Facade](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg "Fig. 11") + +There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade. + +For example, lets take a look how we can create an `XMLHttpRequest` POST request: + +```JavaScript +var http = new XMLHttpRequest(), + url = '/example/new', + params = encodeURIComponent(data); +http.open("POST", url, true); + +http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); +http.setRequestHeader("Content-length", params.length); +http.setRequestHeader("Connection", "close"); + +http.onreadystatechange = function () { + if(http.readyState == 4 && http.status == 200) { + alert(http.responseText); + } +} +http.send(params); +``` +But if we want to post this data using the AngularJS' `$http` service we can: + +```JavaScript +$http({ + method: 'POST', + url: '/example/new', + data: data +}) +.then(function (response) { + alert(response); +}); +``` +or we can even: + +```JavaScript +$http.post('/someUrl', data) +.then(function (response) { + alert(response); +}); +``` +The second option provides pre-configured version, which creates a HTTP POST request to the given URL. + +Even higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections. + +#### Proxy + +>A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. + +![Proxy](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg "Fig. 9") + +We can distinguish three different types of proxy: + +- Virtual Proxy +- Remote Proxy +- Protection Proxy + +In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy. + +In the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`: + +```JavaScript +var User = $resource('/users/:id'), + user = User.get({ id: 42 }); +console.log(user); //{} +``` + +`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server. + +How does this works with AngularJS? Well, lets consider the following snippet: + +```JavaScript +function MainCtrl($scope, $resource) { + var User = $resource('/users/:id'), + $scope.user = User.get({ id: 42 }); +} +``` + +```html + +``` +Initially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view. + +#### Active Record + +>The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. + +![Active Record](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg "Fig. 7") + +AngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core. + +According to the AngularJS' documentation `$resource` is: + +>A factory which creates a resource object that lets you interact with RESTful server-side data sources. +>The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service. + +Here is how `$resource` could be used: + +```JavaScript +var User = $resource('/users/:id'), + user = new User({ + name: 'foo', + age : 42 + }); + +user.$save(); +``` + +The call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations. + +This way we can use the constructor function and its static methods by: + +```JavaScript +User.get({ userid: userid }); +``` + +The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)). + +You can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource). + +Since Martin Fowler states that + +> responsibility of the Active Record object is to take care of the communication with the databse in order to create... + +`$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". + +#### Intercepting Filters + +>Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. + +![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg "Fig. 3") + +In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one. + +In AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`. + +`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error. + +Here is a basic example how you can add interceptors using object literal: + +```JavaScript +$httpProvider.interceptors.push(function($q, dependency1, dependency2) { + return { + 'request': function(config) { + // same as above + }, + 'response': function(response) { + // same as above + } + }; +}); +``` + +### Directives + +#### Composite + +>The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. + +![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg "Fig. 3") + +According to the Gang of Four, MVC is nothing more than combination of: + +- Strategy +- Composite +- Observer + +They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied. + +Lets look at the following example: + +```HTML + + + + + + + Zippy! + + + +``` + +```JavaScript +myModule.directive('zippy', function () { + return { + restrict: 'E', + template: '
', + link: function (scope, el) { + el.find('.header').click(function () { + el.find('.content').toggle(); + }); + } + } +}); +``` + +This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content. + +From the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on... + +In the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node. + +### Interpreter + +>In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. + +![Interpreter](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg "Fig. 6") + +Behind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. +The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions: + +- may contain filters with UNIX like pipe syntax +- don't throw any errors +- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator) +- are evaluated in given context (the context of the current `$scope`) + +Inside the `$parse` service are defined two main components: + +```JavaScript +//Responsible for converting given string into tokens +var Lexer; +//Responsible for parsing the tokens and evaluating the expression +var Parser; +``` + +Once given expression have been tokenized it is cached internally, because of performance concerns. + +The terminal expressions in the AngularJS DSL are defined as follows: + +```JavaScript +var OPERATORS = { + /* jshint bitwise : false */ + 'null':function(){return null;}, + 'true':function(){return true;}, + 'false':function(){return false;}, + undefined:noop, + '+':function(self, locals, a,b){ + //... + }, + '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, + '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, + '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, + '^':function(self, locals, a,b){return a(self, locals)^b(self, locals);}, + '=':noop, + '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);}, + '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);}, + '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);}, + '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);}, + '<':function(self, locals, a,b){return a(self, locals)':function(self, locals, a,b){return a(self, locals)>b(self, locals);}, + '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);}, + '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);}, + '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);}, + '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);}, + '&':function(self, locals, a,b){return a(self, locals)&b(self, locals);}, + '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, + '!':function(self, locals, a){return !a(self, locals);} +}; +``` + +We can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface. + +Each `Client` interprets given AngularJS expression in a specific context - specific scope. + +Few sample AngularJS expressions are: + +```JavaScript +// toUpperCase filter is applied to the result of the expression +// (foo) ? bar : baz +(foo) ? bar : baz | toUpperCase +``` + +#### Template View + +> Renders information into HTML by embedding markers in an HTML page. + +![Template View](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg "Fig. 8") + +The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format. + +Templates are very commonly used especially in the back-end. +For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages. + +For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript. + +For example: + +```html + +``` + +The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value. + +For example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get: + +```html +

Names

+ foo + bar + baz +``` + +AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. +What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope. + +For example: + +```html + +``` + +in the context of the scope: + +```javascript +$scope.names = ['foo', 'bar', 'baz']; +``` + +will produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead. + + +### Scope + +#### Observer + +>The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. + +![Observer](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg "Fig. 7") + +There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes. + +Each AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method): + +```JavaScript +function ExampleCtrl($scope) { + $scope.$on('event-name', function handler() { + //body + }); +} +``` + +In this way the current scope "subscribes" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called. + +The methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain. +For example: + +```JavaScript +function ExampleCtrl($scope) { + $scope.$emit('event-name', { foo: 'bar' }); +} +``` + +The scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked. + +Analogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes. +Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event). + +In the JavaScript community this pattern is better known as publish/subscribe. + +#### Chain of Responsibilities + +>The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. + +![Chain of Responsibilities](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg "Fig. 5") + +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. + +When `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may: + +- Handle the event and pass it to the next scope in the chain +- Handle the event and stop its propagation +- Pass the event to the next scope in the chain without handling it +- Stop the event propagation without handling it + +In the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `"foo received"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. + +```JavaScript +myModule.controller('MainCtrl', function ($scope) { + $scope.$on('foo', function () { + console.log('foo received'); + }); +}); + +myModule.controller('ParentCtrl', function ($scope) { + $scope.$on('foo', function (e) { + console.log('foo received'); + }); +}); + +myModule.controller('ChildCtrl', function ($scope) { + $scope.$emit('foo'); +}); +``` + +The different handlers from the UML diagram above are the different scopes, injected to the controllers. + +#### Command + +>In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. + +![Command](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg "Fig. 11") + +Before continuing with the application of the command pattern lets describe how AngularJS implements data binding. + +When we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can: + +```html + +``` + +Now each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like: + +```html + +``` + +In the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene? + +Each `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span. + +Here are the first a couple of lines of the implementation of `$watch`: + +```javascript +$watch: function(watchExp, listener, objectEquality) { + var scope = this, + get = compileToFn(watchExp, 'watch'), + array = scope.$$watchers, + watcher = { + fn: listener, + last: initWatchVal, + get: get, + exp: watchExp, + eq: !!objectEquality + }; +//... +``` + +We can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`. + +### Controllers + +#### Page Controller + +>An object that handles a request for a specific page or action on a Web site. Martin Fowler + +![Page Controller](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg "Fig. 8") + +According to [4](#references) the page controller: + +>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. + +The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. +Here is an example hierarchy between few controllers: + +```HTML + + + + + +
+ {{user.name}} + +
+ + +``` + +```JavaScript +function MainCtrl($scope, $location, User) { + if (!User.isAuthenticated()) { + $location.path('/unauthenticated'); + } +} + +function ChildCtrl($scope, User) { + $scope.click = function () { + alert('You clicked me!'); + }; + $scope.user = User.get(0); +} +``` + +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. + +### Others + +#### Module Pattern + +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: + +```javascript +var Page = (function () { + + var title; + + function setTitle(t) { + document.title = t; + title = t; + } + + function getTitle() { + return title; + } + + return { + setTitle: setTitle, + getTitle: getTitle + }; +}()); +``` + +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. + +In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. + +The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy: + +```javascript +app.factory('foo', function () { + + function privateMember() { + //body... + } + + function publicMember() { + //body... + privateMember(); + //body + } + + return { + publicMember: publicMember + }; +}); +``` + +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. + +### Data Mapper + +>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. + +![Data Mapper](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg "Fig. 10") + +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.). + +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. + +For instance, lets assume we have application in which each user has: + +- name +- address +- list of friends + +And our API has the methods: + +- `GET /user/:id` - returns the user's name and the address of given user +- `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: + +```javascript +app.factory('User', function ($q) { + + function User(name, address, friends) { + this.name = name; + this.address = address; + this.friends = friends; + } + + User.get = function (params) { + var user = $http.get('/user/' + params.id), + friends = $http.get('/friends/' + params.id); + $q.all([user, friends]) + .then(function (user, friends) { + return new User(user.name, user.address, friends); + }); + }; + return User; +}); +``` + +This way we create pseudo-data mapper, which adapts our API according to the SPA requirements. + +We can use the `User` service by: + +```javascript +function MainCtrl($scope, User) { + User.get({ id: 1 }) + .then(function (data) { + $scope.user = data; + }); +} +``` + +And the following partial: + +```html +
+
+ Name: {{user.name}} +
+
+ Address: {{user.address}} +
+
+ Friends with ids: +
    +
  • {{friend}}
  • +
+
+
+``` + +## References + +1. [Wikipedia](https://en.wikipedia.org/wiki). The source of all brief descriptions of the design patterns is wikipedia. +2. [AngularJS' documentation](https://docs.angularjs.org) +3. [AngularJS' git repository](https://github.com/angular/angular.js) +4. [Page Controller](http://msdn.microsoft.com/en-us/library/ff649595.aspx) +5. [Patterns of Enterprise Application Architecture (P of EAA)](http://martinfowler.com/books/eaa.html) +6. [Using Dependancy Injection to Avoid Singletons](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) +7. [Why would one use the Publish/Subscribe pattern (in JS/jQuery)?](https://stackoverflow.com/questions/13512949/why-would-one-use-the-publish-subscribe-pattern-in-js-jquery) From db25708b757440921fff2dbb3ffd087b32643951 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 19:33:04 +0900 Subject: [PATCH 02/27] Translate Abstract and Introduction --- README-ja-jp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 7f1ba55..0492c4b 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -41,17 +41,17 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a -## Abstract +## 要旨 -One of the best ways to learn something new is to see how the things you already know are used in it. -This document does not intend to make its readers familiar with the design or architectural patterns; it suggests basic understanding of the concepts of the OOP, design patterns and architectural patterns. -The goal of this paper is to describe how different software design and architectural patterns are applied in AngularJS or any AngularJS single-page application. +新しいことを学ぶ際のもっともよい方法の1つとして、既に知っているものがそこでどのように使われているかを観察するという方法があります。 +このドキュメントは読者にデザインやアーキテクチャのパターンに親しんでもらおうとして書かれているものではありませんので、オブジェクト指向やデザイン・パターン、アーキテクチャ・パターンについての基本的な理解をしておくことをおすすめします。 +このドキュメントの目的は、AngularJSやAngularJSのシングル・ページ・アプリケーションにどれだけ様々なソフトウェア・デザインやアーキテクチャのパターンが採用されているかを述べることです。 -## Introduction +## はじめに -The document begins with brief overview of the AngularJS framework. The overview explains the main AngularJS components - directives, filters, controllers, services, scope. The second section lists and describes different design and architectural patterns, which are implemented inside the framework. The patterns are grouped by the AngularJS component they are used in. If some patterns are used inside multiple components it will be explicitly mentioned. +このドキュメントはAngularJSの概要を簡単に見ていくところから始まります。「AngularJSの概要」ではAngularJSの主なコンポーネントとして、ディレクティブ、フィルタ、コントローラ、サービス、スコープを見ていきます。2番目のセクションでは、フレームワークの内部で利用されている別のデザインとアーキテクチャのパターンを解説していきます。いくつかのコンポーネントで利用されているパターンがあった場合は、言及していきます。 -The last section contains a few architectural patterns, which are commonly used inside most of the single-page applications built with AngularJS. +最後のセクションでは、AngularJSで作られているシングル・ページ・アプリケーションでよく使われているいくつかのアーキテクチャ・パターンを解説します。 ## AngularJS overview From c0363e0988087808b350fe782cc7b2283c131ea3 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 20:03:55 +0900 Subject: [PATCH 03/27] Translate AngularJS overview --- README-ja-jp.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 0492c4b..54862a7 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -53,27 +53,27 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a 最後のセクションでは、AngularJSで作られているシングル・ページ・アプリケーションでよく使われているいくつかのアーキテクチャ・パターンを解説します。 -## AngularJS overview +## AngularJSの概要 -AngularJS is a JavaScript framework developed by Google. It intends to provide a solid base for the development of CRUD Single-Page Applications (SPA). -SPA is a web application, which once loaded, does not require full page reload when the user performs any actions with it. This means that all application resources (data, templates, scripts, styles) should be loaded with the initial request or better - the information and resources should be loaded on demand. -Since most of the CRUD applications has common characteristics and requirements, AngularJS intends to provide the optimal set of them out-of-the-box. A few important features of AngularJS are: +AngularJSはCRUDなシングル・ページ・アプリケーション(SPA)開発の基盤を提供する目的で作られたGoogle製のJavascriptフレームワークです。 -- two-way data binding -- dependency injection -- separation of concerns -- testability -- abstraction +SPAとは一度ロードされたら以後ページの全要素を再読込する必要なく、ユーザの操作を受け付けるウェブ・アプリケーションです。これはデータ、テンプレート、スクリプト、スタイルなど全てのリソースを最初のリクエスト時に、または、それが必要になった時にロードすることを意味します。ほとんどすべてのCRUDなアプリケーションは共通の特性と要求を持っているので、AngularJSはそれらのアプリケーションが必要とするものをまとめてすぐに使える最高セットを提供しようとしています。AngularJSのいくつかの重要な特徴は下記のとおりです: -The separation of concerns is achieved by dividing each AngularJS application into separate components, such as: +- 双方向バインディング +- 依存性の注入 +- 関心の分離 +- テストの容易性 +- 抽象化 -- partials -- controllers -- directives -- services -- filters +関心の分離はそれぞれのAngularJSアプリケーションを別々のコンポーネント(下記)に分けることで達成されています。 -These components can be grouped inside different modules, which helps to achieve a higher level of abstraction and handle complexity. Each of the components encapsulates a specific piece of the application's logic. +- パーシャル +- コントローラ +- ディレクティブ +- サービス +- フィルタ + +これらのコンポーネントはそれぞれのモジュールの中でグループ化することができるので、高度な抽象化がやりやすくなりますし、複雑な処理も扱いやすくなっています。それぞれのコンポーネントはアプリケーションの必要なロジックを隠蔽します。 ### Partials From 6562f56c285f4fd6077ed06d633fa4019bc0523f Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 20:31:41 +0900 Subject: [PATCH 04/27] Translate Partials --- README-ja-jp.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 54862a7..a38af37 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -8,8 +8,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [要旨](#要旨) * [はじめに](#はじめに) -* [AngularJS overview](#angularjs-overview) -* [Partials](#partials) +* [AngularJSの概要](#AngularJSの概要) +* [パーシャル](#パーシャル) * [Controllers](#controllers) * [Scope](#scope) * [Directives](#directives) @@ -75,29 +75,29 @@ SPAとは一度ロードされたら以後ページの全要素を再読込す これらのコンポーネントはそれぞれのモジュールの中でグループ化することができるので、高度な抽象化がやりやすくなりますし、複雑な処理も扱いやすくなっています。それぞれのコンポーネントはアプリケーションの必要なロジックを隠蔽します。 -### Partials +### パーシャル -The partials are HTML strings. They may contain AngularJS expressions inside the elements or their attributes. One of the distinctions between AngularJS and the others frameworks is the fact that AngularJS' templates are not in an intermediate format, which needs to be turned into HTML (which is the case with mustache.js and handlebars, for example). +パーシャルはHTMLの文字列です。パーシャルはエレメントまたはアトリビュートの中にAngularJSのエクスプレッションを含むことがあります。AngularJSとその他のフレームワークの違いの1つは、AngularJSのテンプレートがHTMLに変換される前の中間的なフォーマット(例えば、mustache.jsやhandlebarsのようなもの)ではないということです。 -Initially each SPA loads `index.html` file. In the case of AngularJS this file contains a set of standard and custom HTML attributes, elements and comments, which configure and bootstrap the application. Each sub-sequenced user action requires only load of another partial or change of the state of the application, for example through the data binding provided by the framework. +SPAは最初に `index.html` ファイルを読み込みます。AngularJSの場合、このファイルに標準のHTMLアトリビュート、エレメント、コメントに加えカスタムのものも含みます。この段階で、アプリケーションの設定と準備をします。これに続くユーザのアクションは、例えば、フレームワークによって提供されるデータ・バインディングを通すなどして、アプリケーションの他のパーシャルの読み込みや、状態の変更のみで対応します。 -**Sample partial** +**パーシャルのサンプル** ```HTML - + - + ``` -With AngularJS expressions partials define what kind of actions should be performed for handling different user interactions. In the example above the value of the attribute `ng-click` states that the method `changeFoo` of the current *scope* will be invoked. +AngularJSのエクスプレッションでパーシャルはユーザとの対話の中でどのアクションを実行すべきかを定義します。上記の例では、 `ng-click` の値は、現在の *scope* の `changeFoo` メソッドが実行されることを表しています。 ### Controllers From 3292023479742bcea5e3b6ff655609040a0aadc7 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 21:43:29 +0900 Subject: [PATCH 05/27] Translate Controllers --- README-ja-jp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index a38af37..63c1b0d 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -10,7 +10,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [はじめに](#はじめに) * [AngularJSの概要](#AngularJSの概要) * [パーシャル](#パーシャル) -* [Controllers](#controllers) +* [コントローラ](#コントローラ) * [Scope](#scope) * [Directives](#directives) * [Filters](#filters) @@ -99,9 +99,9 @@ SPAは最初に `index.html` ファイルを読み込みます。AngularJSの場 AngularJSのエクスプレッションでパーシャルはユーザとの対話の中でどのアクションを実行すべきかを定義します。上記の例では、 `ng-click` の値は、現在の *scope* の `changeFoo` メソッドが実行されることを表しています。 -### Controllers +### コントローラ -The AngularJS controllers are JavaScript functions, which help handling the user interactions with the web application (for example mouse events, keyboard events, etc.), by attaching methods to the *scope*. All required external, for the controllers, components are provided through the Dependency Injection mechanism of AngularJS. The controllers are also responsible for providing the *model* to the partials by attaching data to the *scope*. We can think of this data as *view model*. +AngularJSのコントローラはユーザとウェブ・アプリケーションとの双方向のやりとり(マウスイベント、キーボードイベントなど)を扱うJavaScriptの関数です。 *scope* に、メソッドを追加することで実現します。コントローラに必要なコンポーネントはAngularJSの依存性の注入によって提供されます。コントローラはまた *scope* にデータを追加することで、パーシャルに *model* を提供する責務を負います。このデータを *view model* と考えることができます。 ```JavaScript function MyController($scope) { @@ -115,12 +115,12 @@ function MyController($scope) { } ``` -For example, if we wire the sample controller above with the partial provided in the previous section the user will be able to interact with the application in few different ways. +例えば、もし上記のサンプルコントローラと、前述のパーシャルをつなげた場合、ユーザはアプリケーションといくつかの方法でコミュニケーションができるようになります。 -1. Change the value of `foo` by typing in the input box. This will immediately reflect the value of `foo` because of the two-way data binding. -2. Change the value of `foo` by clicking the button, which will be labeled `Click me to change foo!`. +1. インプット・ボックスにタイプすることで、 `foo` の値を変更します。双方向バインディングによって、この変更はすぐに `foo` の値に反映されます。 +2. `Click me to change foo!` と表示されているボタンをクリックすることで `foo` の値を変更します。 -All the custom elements, attributes, comments or classes could be recognized as AngularJS *directives* if they are previously defined as ones. +全てのカスタム・エレメント、コメント、また、クラスは事前に定義されている場合、AngularJSの *ディレクティブ* として認識されます。 ### Scope From 9b20d205c41cc4960afd2b70f5c7b08a0a9b63a7 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 21:59:48 +0900 Subject: [PATCH 06/27] Translate Scope --- README-ja-jp.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 63c1b0d..d7cd5c7 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -11,7 +11,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [AngularJSの概要](#AngularJSの概要) * [パーシャル](#パーシャル) * [コントローラ](#コントローラ) -* [Scope](#scope) +* [スコープ](#スコープ) * [Directives](#directives) * [Filters](#filters) * [Services](#services) @@ -122,13 +122,13 @@ function MyController($scope) { 全てのカスタム・エレメント、コメント、また、クラスは事前に定義されている場合、AngularJSの *ディレクティブ* として認識されます。 -### Scope +### スコープ -In AngularJS scope is a JavaScript object, which is exposed to the partials. The scope could contain different properties - primitives, objects or methods. All methods attached to the scope could be invoked by evaluation of AngularJS expression inside the partials associated with the given scope or direct call of the method by any component, which keeps reference to the scope. By using appropriate *directives*, the data attached to the scope could be binded to the view in such a way that each change in the partial will reflect a scope property and each change of a scope property will reflect the partial. +AngularJSではスコープはパーシャルに露出したJavaScriptのオブジェクトです。スコープはプリミティブ、オブジェクト、メソッドなど異なるプロパティを含んでいます。スコープに追加された全てのメソッドはスコープと関連付けられたパーシャルの中でAngularJSのエクスプレッションによって評価され実行されます。また、スコープへの参照を持つコンポーネントから直接呼び出されます。適切な *ディレクティブ* を使うことでスコープに追加されたデータはビューにバインディングされ、パーシャルの中の変更がスコープのプロパティに反映されます。また、プロパティの変更がパーシャルに反映されます。 -Another important characteristics of the scopes of any AngularJS application is that they are connected into a prototypical chain (except scopes, which are explicitly stated as *isolated*). This way any child scope will be able to invoke methods of its parents since they are properties of its direct or indirect prototype. +AngularJSアプリケーションのスコープのもう一つの重要な特性は、それがプロトタイプ・チェーンと結びついていることです( 明示的に *分離* されたものを除きます)。これにより、子のスコープは親のスコープのメソッドを実行することができます。この場合のメソッドは子のスコープの直接、または関節のプロトタイプのプロパティだからです。 -Scope inheritance is illustrated in the following example: +スコープの継承は次の例で説明します: ```HTML
@@ -153,7 +153,7 @@ function ChildCtrl($scope) { } ``` -With `div#child` is associated `ChildCtrl` but since the scope injected inside `ChildCtrl` inherits prototypically from its parent scope (i.e. the one injected inside `BaseCtrl`) the method `foo` is accessible by `button#parent-method`. +`div#child` は `ChildCtrl` と結びついていますが、 `ChildCtrl` に注入されたスコープは親のスコープ( `BaseCtrl` に注入されたスコープ )からプロトタイプ継承をしているので、 `foo` メソッドは `button#parent-method` でアクセス可能になっています。 ### Directives From 7e820331cdbbca9f86d44a5fd3dcbe1ed4d56b23 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 22:10:59 +0900 Subject: [PATCH 07/27] Translate Directives --- README-ja-jp.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index d7cd5c7..6523924 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -12,7 +12,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [パーシャル](#パーシャル) * [コントローラ](#コントローラ) * [スコープ](#スコープ) -* [Directives](#directives) +* [ディレクティブ](#ディレクティブ) * [Filters](#filters) * [Services](#services) * [AngularJS Patterns](#angularjs-patterns) @@ -155,19 +155,19 @@ function ChildCtrl($scope) { `div#child` は `ChildCtrl` と結びついていますが、 `ChildCtrl` に注入されたスコープは親のスコープ( `BaseCtrl` に注入されたスコープ )からプロトタイプ継承をしているので、 `foo` メソッドは `button#parent-method` でアクセス可能になっています。 -### Directives +### ディレクティブ -In AngularJS the directives are the place where all DOM manipulations should be placed. As a rule of thumb, when you have DOM manipulations in your controller you should create a new direcrive or consider refactoring of already existing one, which could handle the required DOM manipulations. -Each directive has a name and logic associated with it. In the simplest case the directive contains only name and definition of *postLink* function, which encapsulates all the logic required for the directive. In more complex cases the directive could contain a lot of properties such as: +AngularJSでは全てのDOM操作がなされるべき場所です。目安としては、コントローラがDOM操作を含む場合、新しいディレクティブを作るか、すでにあるディレクティブが必要なDOM操作ができるようにするためのリファクタリングをするべきでしょう。 +全てのディレクティブは名前と関連するロジックを持っています。最もシンプルなケースとしては、ティレクティブは名前と必要なすべてのロジックをカプセル化するための *postLink* 関数を持ちます。少し複雑なケースでは、下記のようなたくさんのプロパティを持ちます: -- template -- compile function -- link function -- etc... +- テンプレート +- コンパイル関数 +- リンク関数 +- などなど... -By citing the name of the directives they can be used inside the declarative partials. +ディレクティブの名前を利用することで、パーシャルの中で利用することができます。 -Example: +例: ```JavaScript myModule.directive('alertButton', function () { @@ -192,9 +192,9 @@ myModule.directive('alertButton', function () { Click me ``` -In the example above the tag `` will be replaced button element. When the user clicks on the button the string `42` will be alerted. +上記の例では、 `` タグはボタンエレメントに置換えられます。ユーザがボタンをクリックした時に、文字列の `42` がアラートとして表示されます。 -Since the intent of this paper is not to explain the complete API of AngularJS, we will stop with the directives here. +このドキュメントの意図はAngularJSの完全なAPIの解説をすることを意図しているわけではないので、ディレクティブの説明はこの辺りでやめておきます。 ### Filters From 8fe526971f9d15e065e216a60ed0e42fb275a54d Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 22:16:52 +0900 Subject: [PATCH 08/27] Translate Filters --- README-ja-jp.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 6523924..13fad05 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -13,7 +13,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [コントローラ](#コントローラ) * [スコープ](#スコープ) * [ディレクティブ](#ディレクティブ) -* [Filters](#filters) +* [フィルタ](#フィルタ) * [Services](#services) * [AngularJS Patterns](#angularjs-patterns) * [Services](#services-1) @@ -196,11 +196,11 @@ myModule.directive('alertButton', function () { このドキュメントの意図はAngularJSの完全なAPIの解説をすることを意図しているわけではないので、ディレクティブの説明はこの辺りでやめておきます。 -### Filters +### フィルタ -The filters in AngularJS are responsible for encapsulating logic required for formatting data. Usually filters are used inside the partials but they are also accessible in the controllers, directives, *services* and other filters through Dependency Injection. +AngularJSのフィルタはデータをフォーマットするために必要なロジックをカプセル化する責務を負っています。普通、フィルタはパーシャルの中で利用されますが、コントローラやディレクティブ、 *サービス* 、また依存性の注入を用いて他のフィルタの中で利用することも可能です。 -Here is a definition of a sample filter, which changes the given string to uppercase: +与えられた文字列を全て大文字にするサンプルフィルタの定義です。 ```JavaScript myModule.filter('uppercase', function () { @@ -210,13 +210,13 @@ myModule.filter('uppercase', function () { }); ``` -Inside a partial this filter could be used using the Unix's piping syntax: +パーシャルの中ではUnixのパイプ記法でこのフィルタを使うことができます: ```HTML
{{ name | uppercase }}
``` -Inside a controller the filter could be used as follows: +コントローラの中では次のように利用します: ```JavaScript function MyCtrl(uppercaseFilter) { From 1c639e1884da75cc5b4b544ae40f0b6699fe4f59 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sat, 28 Mar 2015 22:33:55 +0900 Subject: [PATCH 09/27] Translate Services --- README-ja-jp.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 13fad05..c17cc0d 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -14,7 +14,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [スコープ](#スコープ) * [ディレクティブ](#ディレクティブ) * [フィルタ](#フィルタ) -* [Services](#services) +* [サービス](#サービス) * [AngularJS Patterns](#angularjs-patterns) * [Services](#services-1) * [Singleton](#singleton) @@ -224,9 +224,9 @@ function MyCtrl(uppercaseFilter) { } ``` -### Services +### サービス -Every piece of logic, which doesn't belong to the components described above should be placed inside a service. Usually services encapsulate the domain specific logic, persistence logic, XHR, WebSockets, etc. When the controllers in the application became too "fat" the repetitive code should be placed inside a service. +上述のコンポーネントに属さない全てのロジックはサービスに格納されるべきです。普通、サービスは問題領域(ドメイン)固有のロジックや、永続化に関わるロジック、XHR、ウェブソケットなどをカプセル化します。アプリケーションの中のコントローラが "肥大化" した際には、何度も利用されるコードをサービスに移し替えるべきです。 ```JavaScript myModule.service('Developer', function () { @@ -240,7 +240,7 @@ myModule.service('Developer', function () { }); ``` -The service could be injected inside any component, which supports dependency injection (controllers, other services, filters, directives). +サービスは依存性の注入を扱えるどのコンポーネント(コントローラ、多のサービス、フィルター、ディレクティブ)にも注入できます。 ```JavaScript function MyCtrl(developer) { From ebfb9d3a80bd537fc1f61b3ba66db6ef1c6c2c19 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 00:36:47 +0900 Subject: [PATCH 10/27] =?UTF-8?q?=E3=82=B7=E3=83=B3=E3=82=B0=E3=83=AB?= =?UTF-8?q?=E3=83=88=E3=83=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-ja-jp.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index c17cc0d..a2f3b70 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -15,9 +15,9 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [ディレクティブ](#ディレクティブ) * [フィルタ](#フィルタ) * [サービス](#サービス) -* [AngularJS Patterns](#angularjs-patterns) -* [Services](#services-1) - * [Singleton](#singleton) +* [AngularJSのパターン](#angularjs-patterns) +* [サービス](#services-1) + * [シングルトン](#singleton) * [Factory Method](#factory-method) * [Decorator](#decorator) * [Facade](#facade) @@ -249,32 +249,32 @@ function MyCtrl(developer) { } ``` -## AngularJS Patterns +## AngularJSのパターン -In the next a couple of sections, we are going to take a look how the traditional design and architectural patterns are composed in the AngularJS components. +次の2つのセクションで、伝統的なデザインとアーキテクチャのパターンがAngularJSのコンポーネントの中でどのように構成されているのかを見ていきます。 -In the last chapter we are going to take a look at some architectural patterns, which are frequently used in the development of Single-Page Applications with (but not limited to) AngularJS. +最後の章ではAngularJSに限らずシングル・ページ・アプリケーションで頻繁に使われるアーキテクチャのパターンについて見ていきます。 -### Services +### サービス -#### Singleton +#### シングルトン ->The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. +> シングルトン・パターンはクラスのインスンタンスを1つに制限するデザイン・パターンです。システムを通してアクションを調整するオブジェクトが1つで良い場合に役に立ちます。この考え方はしばしばシステムに対して、オブジェクトを1つにして効率的に稼働させることや、オブジェクトの数を一定の数以下にを制限することに一般化されます。 -In the UML diagram bellow is illustrated the singleton design pattern. +下記のUMLダイアグラムはシングルトンのデザイン・パターンを表しています。 ![Singleton](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/singleton.svg "Fig. 1") -When given dependency is required by any component, AngularJS resolves it using the following algorithm: +依存性がコンポーネントに必要とされる際に、AngularJSは次のアルゴリズムを使って依存性の解決を行っています: -- Takes its name and makes a lookup at a hash map, which is defined into a lexical closure (so it has a private visibility). -- If the dependency exists AngularJS pass it as parameter to the component, which requires it. -- If the dependency does not exists: - - AngularJS instantiate it by calling the factory method of its provider (i.e. `$get`). Note that instantiating the dependency may require recursive call to the same algorithm, for resolving all the dependencies required by the given dependency. This process may lead to circular dependency. - - AngularJS caches it inside the hash map mentioned above. - - AngularJS passes it as parameter to the component, which requires it. +- 依存性の名前で語彙のクロージャの中に定義されているハッシュ・マップを検索します(プライベートにアクセスできるようになっています)。 +- 依存性がAngularJSの中に存在する場合は、それを必要としているコンポーネントにパラメタとして渡します。 +- 依存性が存在しない場合は: + - AngularJSはプロバイダのファクトリ・メソッド( `$get` )を用いてその依存性をインスタンス化します。 依存性のインスタンス化は必要に応じて、同じアルゴリズムを用いて再帰的に行われます。このプロセスは循環依存を起こします。 + - AngularJSはそのインスタンスを上述のハッシュ・マップにキャッシュします。 + - AngularJSは必要としているコンポーネントにパラメタとしてそのインスタンスを渡します。 -We can take better look at the AngularJS' source code, which implements the method `getService`: +`getService` メソッドが実装されている部分のソースコードを見たほうが良いでしょう。 ```JavaScript function getService(serviceName) { @@ -300,14 +300,14 @@ function getService(serviceName) { } ``` -We can think of each service as a singleton, because each service is instantiated no more than a single time. We can consider the cache as a singleton manager. There is a slight variation from the UML diagram illustrated above because instead of keeping static, private reference to the singleton inside its constructor function, we keep the reference inside the singleton manager (stated in the snippet above as `cache`). +サービスは一度しかインスタンス化されないので、全てのサービスをシングルトンと考えることができます。キャッシュはシングルトンのマネージャと考えることができます。上記のUMLダイアグラムと少し違いがあります。コンストラクタ関数の中のシングルトンオブジェクトにスタティックでプライベートな参照を保つ代わりに、シングルトン・マネージャ(上記のコードの中の `cache` )の中に参照を保ちます。 -This way the services are actually singletons but not implemented through the Singleton pattern, which provides a few advantages over the standard implementation: +このように、サービスは実際にはシングルトンですが、シングルトン・パターンを通して実装されているわkではありません。これは、一般的な実装に比べていくつかの利点があります。 -- It improves the testability of your source code -- You can control the creation of singleton objects (in our case the IoC container controls it for us, by instantiating the singletons lazy) +- テストをしやすくします。 +- シングルトンオブジェクトの生成をコントロールできます(私達のケースでは、IoCコンテナがシングルトンを遅延インスタンス化することでコントロールしています)。 -For further discussion on this topic Misko Hevery's [article](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) in the Google Testing blog could be considered. +このトピックに関する更に一歩踏み込んだ議論のために、Google Testing blogのMisko Heveryの [記事](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) を考慮にいれましょう。 #### Factory Method From 6d4ba378168192c686dd74e73c81a2e1082c9590 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 01:23:19 +0900 Subject: [PATCH 11/27] Translate Factory Method --- README-ja-jp.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index a2f3b70..ce30397 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -17,8 +17,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [サービス](#サービス) * [AngularJSのパターン](#angularjs-patterns) * [サービス](#services-1) - * [シングルトン](#singleton) - * [Factory Method](#factory-method) + * [シングルトン](#シングルトン) + * [ファクトリ・メソッド](#ファクトリ・メソッド) * [Decorator](#decorator) * [Facade](#facade) * [Proxy](#proxy) @@ -259,7 +259,7 @@ function MyCtrl(developer) { #### シングルトン -> シングルトン・パターンはクラスのインスンタンスを1つに制限するデザイン・パターンです。システムを通してアクションを調整するオブジェクトが1つで良い場合に役に立ちます。この考え方はしばしばシステムに対して、オブジェクトを1つにして効率的に稼働させることや、オブジェクトの数を一定の数以下にを制限することに一般化されます。 +>シングルトン・パターンはクラスのインスンタンスを1つに制限するデザイン・パターンです。システムを通してアクションを調整するオブジェクトが1つで良い場合に役に立ちます。この考え方はしばしばシステムに対して、オブジェクトを1つにして効率的に稼働させることや、オブジェクトの数を一定の数以下にを制限することに一般化されます。 下記のUMLダイアグラムはシングルトンのデザイン・パターンを表しています。 @@ -309,20 +309,20 @@ function getService(serviceName) { このトピックに関する更に一歩踏み込んだ議論のために、Google Testing blogのMisko Heveryの [記事](http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html) を考慮にいれましょう。 -#### Factory Method +#### ファクトリ・メソッド ->The factory method pattern is a creational pattern, which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class, which can be overridden when inherited in derived classes; rather than by a constructor. +>ファクトリ・メソッド・パターンは生成のパターンです。生成のパターンは生成するクラス指定のないオブジェクトを生成する際に生じる問題をうまく扱うためにファクトリ・メソッドを利用します。コンストラクタではなく、インターフェイス(抽象クラス)で指定されているファクトリメソッド、実装クラス(具象クラス)に実装されているファクトリメソッド、また、継承される可能性もあるのですが、ベースクラスに実装されているファクトリメソッドを通してオブジェクトが生成される場合に利用されます。 ![Factory Method](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/factory-method.svg "Fig. 2") -Lets consider the following snippet: +次のスニペットを考えてみましょう: ```JavaScript myModule.config(function ($provide) { $provide.provider('foo', function () { var baz = 42; return { - //Factory method + //ファクトリ・メソッド $get: function (bar) { var baz = bar.baz(); return { @@ -335,11 +335,11 @@ myModule.config(function ($provide) { ``` -In the code above we use the `config` callback in order to define new "provider". Provider is an object, which has a method called `$get`. Since in JavaScript we don't have interfaces and the language is duck-typed there is a convention to name the factory method of the providers that way. +新しい "プロバイダ" を定義するために、上記のコードで `config` コールバックを利用しています。プロバイダは `$get` メソッドを持っているオブジェクトです。JavaScriptでインターフェイスを持たず、ダックタイプされているので、このようにプロバイダのファクトリ・メソッドを名付ける慣例があります。 -Each service, filter, directive and controller has a provider (i.e. object which factory method, called `$get`), which is responsible for creating the component's instance. +サービス、フィルタ、ディレクティブ、コントローラはそれぞれコンポーネントのインスタンスを生成する責務を負うプロバイダ( `$get` を持つオブジェクト)を持ちます。 -We can dig a little bit deeper in AngularJS' implementation: +AngularJSの実装をもう少し深く探っていくことが出います: ```JavaScript //... @@ -375,7 +375,7 @@ function invoke(fn, self, locals, serviceName){ ); } if (!fn.$inject) { - // this means that we must be an array. + // これは配列でなければいけないことを意味しています fn = fn[length]; } @@ -383,21 +383,21 @@ function invoke(fn, self, locals, serviceName){ } ``` -From the example above we can notice how the `$get` method is actually used: +上記の例から、 `$get` メソッドが実際に利用されていることを知ることができます: ```JavaScript instanceInjector.invoke(provider.$get, provider, undefined, servicename) ``` -The snippet above calls the `invoke` method of `instanceInjector` with the factory method (i.e. `$get`) of given service, as first argument. Inside `invoke`'s body `annotate` is called with first argument the factory method. Annotate resolves all dependencies through the dependency injection mechanism of AngularJS, which was considered above. When all dependencies are resolved the factory method is being called: `fn.apply(self, args)`. +上記のスニペットは `instanceInjector` の `invoke` メソッドを最初の引数にサービスのファクトリ・メソッド( `$get` )を指定して呼んでいます。 `invoke`メソッドの中では、最初の引数にファクトリメソッドを指定して `annotate` が呼ばれています。アノテートはAngularJSの依存性の注入メカニズムを通して全ての依存性を解決します。全ての依存性の解決ができた時、ファクトリ・メソッドが呼ばれます: `fn.apply(self, args)` 。 -If we think in terms of the UML diagram above we can call the provider a "ConcreteCreator" and the actual component, which is being created a "Product". +上記のUMLダイアグラムの観点から考えると、プロバイダを "ConcreteCreator" と呼ぶことができます。そして、実際のコンポーネントは作られた "Product" となります。 -There are a few benefits of using the factory method pattern in this case, because of the indirection it creates. This way the framework can take care of the boilerplates during the instantiation of new components like: +ファクトリ・メソッドの間接性にファクトリ・メソッドを使ういくつかの利点があります。この方法で、フレームワークは新しいコンポーネントを生成する際の基本的な中身に注意を払うことができます: -- The most appropriate moment, when the component needs to be instantiated -- Resolving all the dependencies required by the component -- The number of instances the given component is allowed to have (for services and filters only a single one but multiple for the controllers) +- コンポーネントがインスタンス化される最も適切なタイミング +- コンポーネントに必要とされるすべての依存性の解決 +- コンポーネントが持つことを許されているインスタンスの数(サービスとフィルタは1つ。コントローラは複数) #### Decorator From ef8e3d4d5c691ffd677ddc453b6f387e5b63be60 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 13:27:57 +0900 Subject: [PATCH 12/27] Translate Decorator --- README-ja-jp.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index ce30397..27b1e9f 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -15,11 +15,11 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [ディレクティブ](#ディレクティブ) * [フィルタ](#フィルタ) * [サービス](#サービス) -* [AngularJSのパターン](#angularjs-patterns) -* [サービス](#services-1) +* [AngularJSのパターン](#AngularJSのパターン) +* [サービス](#サービス-1) * [シングルトン](#シングルトン) * [ファクトリ・メソッド](#ファクトリ・メソッド) - * [Decorator](#decorator) + * [デコレータ](#デコレータ) * [Facade](#facade) * [Proxy](#proxy) * [Active Record](#active-record) @@ -339,7 +339,7 @@ myModule.config(function ($provide) { サービス、フィルタ、ディレクティブ、コントローラはそれぞれコンポーネントのインスタンスを生成する責務を負うプロバイダ( `$get` を持つオブジェクト)を持ちます。 -AngularJSの実装をもう少し深く探っていくことが出います: +AngularJSの実装をもう少し深く探っていくことができます: ```JavaScript //... @@ -399,13 +399,13 @@ instanceInjector.invoke(provider.$get, provider, undefined, servicename) - コンポーネントに必要とされるすべての依存性の解決 - コンポーネントが持つことを許されているインスタンスの数(サービスとフィルタは1つ。コントローラは複数) -#### Decorator +#### デコレータ ->The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. +>デコレータ・パターン(アダプタ・パターンの別名でもあるラッパーとしても知られています。)は個別のオブジェクトに静的であっても動的であっても同じクラスの他のオブジェクトに影響をあたえることなく振る舞いを追加するデザイン・パターンです。 ![Decorator](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/decorator.svg "Fig. 4") -AngularJS provides out-of-the-box way for extending and/or enhancing the functionality of already existing services. Using the method `decorator` of `$provide` you can create "wrapper" of any service you have previously defined or used by a third-party: +AngularJSは既に存在するサービスの機能を追加したり、強化するための簡単な方法を提供しています。 `$provide` の `decorator` メソッドを使うことによりカスタムのサービスやサード・パーティで使われているサービスに "ラッパー" を作ることができます: ```JavaScript myModule.controller('MainCtrl', function (foo) { @@ -434,10 +434,11 @@ myModule.config(function ($provide) { }); }); ``` -The example above defines new service called `foo`. In the `config` callback is called the method `$provide.decorator` with first argument `"foo"`, which is the name of the service, we want to decorate and second argument factory function, which implements the actual decoration. `$delegate` keeps reference to the original service `foo`. Using the dependency injection mechanism of AngularJS, reference to this local dependency is passed as first argument of the constructor function. -We decorate the service by overriding its method `bar`. The actual decoration is simply extending `bar` by invoking one more `console.log statement` - `console.log('Decorated');` and after that call the original `bar` method with the appropriate context. -Using this pattern is especially useful when we need to modify the functionality of third party services. In cases when multiple similar decorations are required (like performance measurement of multiple methods, authorization, logging, etc.), we may have a lot of duplications and violate the DRY principle. In such cases it is useful to use [aspect-oriented programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming). The only AOP framework for AngularJS I'm aware of could be found at [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop). +上記の例では `foo` という名の新しいサービスを定義しています。 `config` のコールバックは、最初の引数をデコレートしたいサービス名である `foo` として `$provide.decorator` を呼び出しています。2番目の引数は実際のデコレーションを実装しているファクトリ関数です。 `$delegate` はオリジナルサービス `foo` への参照を持っています。AngularJSの依存性の注入メカニズムを使うことにより、ローカルな依存性への参照はコンストラクタ関数の最初の引数として渡されます。 +`bar` メソッドを上書きすることによってサービスをデコレートします。実際のデコレーションは単に `bar` でもう一つの `console.log ステートメント` - `console.log('Dcorated');` を実行するように拡張することです。その後、オリジナルの 'bar' メソッドを適切な文脈で利用します。 + +サード・パーティの機能を変更する必要がある場合特にこのパターンは役に立ちます。複数の似たようなデコレーションが必要となった時(複数のメソッドのパフォーマンス計測、認証、ログ出力など)、複製がたくさんでき、DRYの原則を破ってしまいます。そのような場合には[アスペクト指向プログラミング(AOP)](http://en.wikipedia.org/wiki/Aspect-oriented_programming)を取り入れるとよいでしょう。AngularJSで利用できるAOPフレームワークとしては、分かる範囲では唯一、 [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop) があります。 #### Facade From ee36b18b8ae7f195ddcb82395c7b2f4810872bff Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 13:49:29 +0900 Subject: [PATCH 13/27] Translate Facade --- README-ja-jp.md | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 27b1e9f..5ebc410 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -20,9 +20,9 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [シングルトン](#シングルトン) * [ファクトリ・メソッド](#ファクトリ・メソッド) * [デコレータ](#デコレータ) - * [Facade](#facade) - * [Proxy](#proxy) - * [Active Record](#active-record) + * [ファサード](#ファサード) + * [プロキシ](#プロキシ) + * [アクティブ・レコード](#アクティブ・レコード) * [Intercepting Filters](#intercepting-filters) * [Directives](#directives-1) * [Composite](#composite) @@ -440,23 +440,23 @@ myModule.config(function ($provide) { サード・パーティの機能を変更する必要がある場合特にこのパターンは役に立ちます。複数の似たようなデコレーションが必要となった時(複数のメソッドのパフォーマンス計測、認証、ログ出力など)、複製がたくさんでき、DRYの原則を破ってしまいます。そのような場合には[アスペクト指向プログラミング(AOP)](http://en.wikipedia.org/wiki/Aspect-oriented_programming)を取り入れるとよいでしょう。AngularJSで利用できるAOPフレームワークとしては、分かる範囲では唯一、 [github.com/mgechev/angular-aop](https://github.com/mgechev/angular-aop) があります。 -#### Facade +#### ファサード ->A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can: +>ファサードはクラス・ライブラリのような多くのコードにシンプルなインターフェイスを提供するオブジェクトです。ファサードは次のことができます: ->1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks; +>1. ソフトウェア・ライブラリを理解しやすく、使いやすくします。またテストをしやすくします。ファサードはよく使われるタスクを実行するための使いやすいメソッドを持つからです; ->2. make the library more readable, for the same reason; +>2. 同じ理由から、ライブラリを読みやすくします。 ->3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system; +>3. 外部のコードのライブラリの処理に対する依存性を減らします。なぜなら、ほとんどのコードはファサードを使うのでシステム開発の際の柔軟性を許容します。 ->4. wrap a poorly designed collection of APIs with a single well-designed API (as per task needs). +>4. うまくデザインされていないAPI群を、(タスクが必要とする単位で)よくデザインされたAPIとしてラップします。 ![Facade](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/facade.svg "Fig. 11") -There are a few facades in AngularJS. Each time you want to provide higher level API to given functionality you practically create a facade. +AngularJSにはいくつかのファサードがあります。高レベルのAPIを提供された機能に追加したいとき、実際にファサードを作ることになります。 -For example, lets take a look how we can create an `XMLHttpRequest` POST request: +例えば、 `XMLHttpRequest` のPOSTリクエストをどのように作るか見て行きましょう: ```JavaScript var http = new XMLHttpRequest(), @@ -475,7 +475,8 @@ http.onreadystatechange = function () { } http.send(params); ``` -But if we want to post this data using the AngularJS' `$http` service we can: + +ただ、このデータをポストしたいとき、AngularJSの `$http` サービスを使うことができます: ```JavaScript $http({ @@ -487,7 +488,8 @@ $http({ alert(response); }); ``` -or we can even: + +また、このように書いても同じです: ```JavaScript $http.post('/someUrl', data) @@ -495,9 +497,10 @@ $http.post('/someUrl', data) alert(response); }); ``` -The second option provides pre-configured version, which creates a HTTP POST request to the given URL. -Even higher level of abstraction is being created by `$resource`, which is build over the `$http` service. We will take a further look at this service in [Active Record](#active-record) and [Proxy](#proxy) sections. +2番目の例は、与えられたURLでHTTP POSTリクエストを作る様に設定されたバージョンです。 + +更に高レベルの抽象化は `$http` サービスをもとに構築された `$resource` で行うことができます。このサービスに関しては、 [アクティブ・レコード](#アクティブ・レコード) と [プロキシ](#プロキシ) のところでもう少し深く見ていきます。 #### Proxy From 5f4a5889d8acfca44afc23a3c751a1de0b622111 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 14:14:04 +0900 Subject: [PATCH 14/27] Translate Proxy --- README-ja-jp.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 5ebc410..3562ce6 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -476,7 +476,7 @@ http.onreadystatechange = function () { http.send(params); ``` -ただ、このデータをポストしたいとき、AngularJSの `$http` サービスを使うことができます: +しかし、このデータをポストしたいとき、AngularJSの `$http` サービスを使うことができます: ```JavaScript $http({ @@ -502,21 +502,21 @@ $http.post('/someUrl', data) 更に高レベルの抽象化は `$http` サービスをもとに構築された `$resource` で行うことができます。このサービスに関しては、 [アクティブ・レコード](#アクティブ・レコード) と [プロキシ](#プロキシ) のところでもう少し深く見ていきます。 -#### Proxy +#### プロキシ ->A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. +>プロキシの最も一般的な形は、何か別のものに対するインターフェイスとしての振る舞うクラスの働きです。プロキシは、通信接続、メモリ上の大きなオブジェクト、ファイル、複製するのが不可能だったりコストが掛かり過ぎるその他のリソースなどいろいろなもののインターフェイスになることができます。 ![Proxy](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/proxy.svg "Fig. 9") -We can distinguish three different types of proxy: +プロキシは3つの種類に分けることができます: -- Virtual Proxy -- Remote Proxy -- Protection Proxy +- バーチャル・プロキシ +- リモート・プロキシ +- プロテクション・プロキシ -In this sub-chapter we are going to take a look at AngularJS' implementation of Virtual Proxy. +この副章では、AngularJSのバーじゃる・プロキシの実装を見ていきます。 -In the snippet bellow, there is a call to the `get` method of `$resource` instance, called `User`: +下記のスニペットでは、 `User` という名の `$resource` インスタンスの `get` メソッドを呼んでいます: ```JavaScript var User = $resource('/users/:id'), @@ -524,9 +524,9 @@ var User = $resource('/users/:id'), console.log(user); //{} ``` -`console.log` would outputs an empty object. Since the AJAX request, which happens behind the scene, when `User.get` is invoked, is asynchronous, we don't have the actual user when `console.log` is called. Just after `User.get` makes the GET request it returns an empty object and keeps reference to it. We can think of this object as virtual proxy (a simple placeholder), which would be populated with the actual data once the client receives response by the server. +`console.log` は空のオブジェクトを出力します。 AJAXリクエストは、 `User.get` が呼ばれた時点で非同期で処理されていて、 `console.log` が呼ばれた時点ではまだ実際のユーザが準備されていないのです。 `User.get` はGETリクエストをし、空のオブジェクトを返しますが、参照は持ち続けています。このオブジェクトをバーチャル・プロキシ(単に、プレースホルダーとも)考えることができます。クライアントがサーバからレスポンスを受け取ると実際のデータが格納されます。 -How does this works with AngularJS? Well, lets consider the following snippet: +これはAngularJSでどのように使われるのでしょうか? 次のスニペットを考えてみましょう: ```JavaScript function MainCtrl($scope, $resource) { @@ -538,7 +538,8 @@ function MainCtrl($scope, $resource) { ```html ``` -Initially when the snippet above executes, the property `user` of the `$scope` object will be with value an empty object (`{}`), which means that `user.name` will be undefined and nothing will be rendered. Internally AngularJS will keep reference to this empty object. Once the server returns response for the get request, AngularJS will populate the object with the data, received from the server. During the next `$digest` loop AngularJS will detect change in `$scope.user`, which will lead to update of the view. + +上記のスニペットが事項された直後、 `$scope` の `user` プロパティは空のオブジェクト( `{}` )になります。 `user.name` はundefinedとなり何もレンダリングされません。内部ではAngularJSはこの空のオブジェクトに参照を保っています。サーバがGETリクエストのレスポンスを返すと、AngularJSはサーバから受け取ったデータをオブジェクトに格納します。次の `$digest` ループでAngularJSは `$scope.user` の変更を検知し、ビューの更新に移ります。 #### Active Record From aaa3b31a19cdab2df9409fd64da230a38f0fee1d Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 14:36:26 +0900 Subject: [PATCH 15/27] Translate Active Record --- README-ja-jp.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 3562ce6..b9096e2 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -541,20 +541,20 @@ function MainCtrl($scope, $resource) { 上記のスニペットが事項された直後、 `$scope` の `user` プロパティは空のオブジェクト( `{}` )になります。 `user.name` はundefinedとなり何もレンダリングされません。内部ではAngularJSはこの空のオブジェクトに参照を保っています。サーバがGETリクエストのレスポンスを返すと、AngularJSはサーバから受け取ったデータをオブジェクトに格納します。次の `$digest` ループでAngularJSは `$scope.user` の変更を検知し、ビューの更新に移ります。 -#### Active Record +#### アクティブ・レコード ->The Active Record object is an object, which carries both data and behavior. Usually most of the data in these objects is persistent, responsibility of the Active Record object is to take care of the communication with the database in order to create, update, retrieve or delete the data. It may delegate this responsibility to lower level objects but calls to instance or static methods of the active record object cause the database communication. +>アクティブ・レコードはデータと振る舞いを持つオブジェクトです。普通、アクティブ・レコード内のほとんどのデータは永続的です。アクティブ・レコード・オブジェクトの責務はデータの生成、更新、取得、削除をするためのデータベースとのやりとりを適切に行うことです。この責務を更に低レベルのオブジェクトに委譲することはありますが、アクティブ・レコード・オブジェクトのインスタンスや静的メソッドの呼び出しはデータベースとのやりとりをもたらします。 ![Active Record](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/active-record.svg "Fig. 7") -AngularJS defines a service called `$resource`. In the current version of AngularJS (1.2+) it is being distributed in module outside of the AngularJS' core. +AngularJSは `$resource` と呼ばれるサービスを定義しています。 AngularJS(1.2+)ではAngularJSのコアの外部モジュールとして配布されています。 -According to the AngularJS' documentation `$resource` is: +AngularJSのドキュメントによると `$resource` は: ->A factory which creates a resource object that lets you interact with RESTful server-side data sources. ->The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service. +>RESTFullサーバ・サイド・データ構造とやりとりするためのリソース・オブジェクトを生成するファクトリ。 +> 返却されたリソース・オブジェクトは低レベルの$httpサービスを直接操作する必要なく、高レベルの振る舞いを提供するアクションを持っています。 -Here is how `$resource` could be used: +`$resource` がどのように使われているかしめします: ```JavaScript var User = $resource('/users/:id'), @@ -566,23 +566,23 @@ var User = $resource('/users/:id'), user.$save(); ``` -The call of `$resource` will create a constructor function for our model instances. Each of the model instances will have methods, which could be used for the different CRUD operations. +`$resource` の呼び出しはモデルインスタンスのコンストラクタ関数を生成します。それぞれのモデルインスタンスはCRUDオペレーションに応じたメソッドを持つことになります。 -This way we can use the constructor function and its static methods by: +このように、コンストラクタ関数と静的メソッドを使います: ```JavaScript User.get({ userid: userid }); ``` -The code above will immediately return an empty object and keep reference to it. Once the response have been successfully returned and parsed, AngularJS will populate this object with the received data (see [proxy](#proxy)). +上記のコードはすぐに空のオブジェクトを返し、それに対して参照を持ち続けます。レスポンスが成功して、パースされるとAngularJSは受け取ったデータをオブジェクトに格納します(参考: [プロキシ](#プロキシ) )。 -You can find more details for `$resource` [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) and [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource). +`$resource` についての詳細は、 [The magic of $resource](http://blog.mgechev.com/2014/02/05/angularjs-resource-active-record-http/) や [AngularJS' documentation](https://docs.angularjs.org/api/ngResource/service/$resource) で確認できます。 -Since Martin Fowler states that +Martin Fowlerがこのように宣言しているように: -> responsibility of the Active Record object is to take care of the communication with the databse in order to create... +> アクティブ・レコード・オブジェクトの責務はデータの生成、更新、取得、削除をするためのデータベースとのやりとりを適切に行うことです。... -`$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". +`$resource` はデータベースではなくRESTfulサービスとのやりとりをするので、アクティブ・レコード・パターンそのままの実装ではありません。そうは言っても、 "アクティブ・レコードのようなRESTFulコミュニケーション" と考えることができます。 #### Intercepting Filters From d0ac2a898d8067e498ad5ff473a7899e35ff6f2e Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 14:40:59 +0900 Subject: [PATCH 16/27] Update Table of Contents --- README-ja-jp.md | 50 ++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index b9096e2..6004598 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -9,33 +9,33 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [要旨](#要旨) * [はじめに](#はじめに) * [AngularJSの概要](#AngularJSの概要) -* [パーシャル](#パーシャル) -* [コントローラ](#コントローラ) -* [スコープ](#スコープ) -* [ディレクティブ](#ディレクティブ) -* [フィルタ](#フィルタ) -* [サービス](#サービス) + * [パーシャル](#パーシャル) + * [コントローラ](#コントローラ) + * [スコープ](#スコープ) + * [ディレクティブ](#ディレクティブ) + * [フィルタ](#フィルタ) + * [サービス](#サービス) * [AngularJSのパターン](#AngularJSのパターン) -* [サービス](#サービス-1) - * [シングルトン](#シングルトン) - * [ファクトリ・メソッド](#ファクトリ・メソッド) - * [デコレータ](#デコレータ) - * [ファサード](#ファサード) - * [プロキシ](#プロキシ) - * [アクティブ・レコード](#アクティブ・レコード) - * [Intercepting Filters](#intercepting-filters) -* [Directives](#directives-1) - * [Composite](#composite) + * [サービス](#サービス-1) + * [シングルトン](#シングルトン) + * [ファクトリ・メソッド](#ファクトリ・メソッド) + * [デコレータ](#デコレータ) + * [ファサード](#ファサード) + * [プロキシ](#プロキシ) + * [アクティブ・レコード](#アクティブ・レコード) + * [Intercepting Filters](#intercepting-filters) + * [Directives](#directives-1) + * [Composite](#composite) * [Interpreter](#interpreter) - * [Template View](#template-view) -* [Scope](#scope-1) - * [Observer](#observer) - * [Chain of Responsibilities](#chain-of-responsibilities) - * [Command](#command) -* [Controller](#controller-1) - * [Page Controller](#page-controller) -* [Others](#others) - * [Module Pattern](#module-pattern) + * [Template View](#template-view) + * [Scope](#scope-1) + * [Observer](#observer) + * [Chain of Responsibilities](#chain-of-responsibilities) + * [Command](#command) + * [Controller](#controller-1) + * [Page Controller](#page-controller) + * [Others](#others) + * [Module Pattern](#module-pattern) * [Data Mapper](#data-mapper) * [References](#references) From 06853dcc6356415c3356b2e66aab352ecfc0cc8f Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 15:12:34 +0900 Subject: [PATCH 17/27] Translate Intercepting Filters --- README-ja-jp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 6004598..306890f 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -23,7 +23,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [ファサード](#ファサード) * [プロキシ](#プロキシ) * [アクティブ・レコード](#アクティブ・レコード) - * [Intercepting Filters](#intercepting-filters) + * [傍受フィルタ](#傍受フィルタ) * [Directives](#directives-1) * [Composite](#composite) * [Interpreter](#interpreter) @@ -584,19 +584,19 @@ Martin Fowlerがこのように宣言しているように: `$resource` はデータベースではなくRESTfulサービスとのやりとりをするので、アクティブ・レコード・パターンそのままの実装ではありません。そうは言っても、 "アクティブ・レコードのようなRESTFulコミュニケーション" と考えることができます。 -#### Intercepting Filters +#### 傍受フィルタ ->Create a chain of composable filters to implement common pre-processing and post-processing tasks during a Web page request. +>ウェブページのリクエストの際の共通の事前処理と事後処理タスクを実装するために構成可能なフィルタ・チェーンを作成する ![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/intercepting-filters.svg "Fig. 3") -In some cases you need to do some kind of pre and/or post processing of HTTP requests. In the case of the Intercepting Filters you pre/post process given HTTP request/response in order to include logging, security or any other concern, which is influenced by the request body or headers. Basically the Intercepting Filters pattern include a chain of filters, each of which process data in given order. The output of each filter is input of the next one. +HTTPリクエストの際に、事前処理、または、事後処理、またはその両方をしたい時があります。傍受フィルタを使うと、ログ出力、セキュリティまたリクエストのボディやヘッダによって影響を受ける関心事に対応するために、HTTPリクエストやレスポンスに事前・事後プロセスを追加することができます。基本的に傍受フィルタ・パターンはフィルタのチェーンを含みます。それぞれのフィルタは順番通りにデータを処理します。それぞれのフィルタのアウトプットは次のフィルタのインプットになります。 -In AngularJS we have the idea of the Intercepting Filters in `$httpProvider`. `$httpProvider` has an array property called `interceptors`, which contains a list of objects. Each object may have properties called: `request`, `response`, `requestError`, `responseError`. +AngularJSでは `$httpProvider` で母樹フィルタのアイディアを利用しています。 `$httpProvider` は `interceptors` と呼ばれている配列プロパティを持っています。それぞれのオブジェクトは `リクエスト` , `レスポンス` , `requestError` , `responseError` と呼ばれるプロパティを必要に応じて持ちます。 -`requestError` is an interceptor, which gets called when a previous interceptor threw an error or resolved with a rejection, respectively `responseError` is being called when the previous `response` interceptor has thrown an error. +`requestError` は一つ前のインターセプタがエラーを投げた時や、処理の拒否を行って終了した時に呼び出されるインターセプタです。 `responseError` は、一つ前の `response` インターセプタがエラーを投げた時に呼び出されます。 -Here is a basic example how you can add interceptors using object literal: +これは、インターセプタをオブジェクト・リテラルで利用する例です: ```JavaScript $httpProvider.interceptors.push(function($q, dependency1, dependency2) { From 597beeb2bcf5057c158f1c2a123c3baf21bee92e Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 15:27:56 +0900 Subject: [PATCH 18/27] Translate Composit --- README-ja-jp.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 306890f..ea0c4a6 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -24,8 +24,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [プロキシ](#プロキシ) * [アクティブ・レコード](#アクティブ・レコード) * [傍受フィルタ](#傍受フィルタ) - * [Directives](#directives-1) - * [Composite](#composite) + * [ディレクティブ](#ディレクティブ-1) + * [コンポジット](#コンポジット) * [Interpreter](#interpreter) * [Template View](#template-view) * [Scope](#scope-1) @@ -611,23 +611,23 @@ $httpProvider.interceptors.push(function($q, dependency1, dependency2) { }); ``` -### Directives +### ディレクティブ -#### Composite +#### コンポジット ->The composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. +>コンポジット・パターンは分離をするためのデザイン・パターンです。コンポジット・パターンはオブジェクトのまとまりは1つのオブジェクトのインスタンスとして同じように扱われるべきとしています。コンポジットの意図は、複数のオブジェクトを部分と全体の階層構造を表す3つの構造に "構成する" ということです。 ![Composite](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/composite.svg "Fig. 3") -According to the Gang of Four, MVC is nothing more than combination of: +Gang of Fourによると、MVCは次の組み合わせであるに過ぎないということです: -- Strategy -- Composite -- Observer +- ストラテジ +- コンポジット +- オブザーバ -They state that the view is composition of components. In AngularJS the situation is similar. Our views are formed by a composition of directives and DOM elements, on which these directives could be applied. +これらはビューはコンポーネントのコンポジションであるということを表しています。AngularJSでは状況は似ています。ビューはディレクティブとディレクティブが適用されていることもあるDOM要素のコンポジションです。 -Lets look at the following example: +次の例を見てみましょう: ```HTML @@ -656,11 +656,11 @@ myModule.directive('zippy', function () { }); ``` -This example defines a simple directive, which is a UI component. The defined component (called "zippy") has header and content. Click on its header toggles the visibility of the content. +この例はUIコンポーネントとしてのシンプルなディレクティブを定義しています。定義されたコンポーネント("zippy")はヘッダとコンテントを持っています。ヘッダをクリックするとコンテントが見え隠れします。 -From the first example we can note that the whole DOM tree is a composition of elements. The root component is the `html` element, directly followed by the nested elements `head` and `body` and so on... +最初の例から、全てのDOM要素の木構造は要素のコンポジションであると気づきます。ルート・コンポーネントは `html` 要素です。そしてそこに、 `head` や `body` などが続きます。 -In the second, JavaScript, example we see that the `template` property of the directive, contains markup with `ng-transclude` directive inside it. So this means that inside the directive `zippy` we have another directive called `ng-transclude`, i.e. composition of directives. Theoretically we can nest the components infinitely until we reach a leaf node. +2番目のJavaScriptの例から、ディレクティブの `template` プロパティは `ng-transclude` ディレクティブが付加されたマークアップを見つけることができます。 `zippy` ディレクティブの中で別のディレクティブである `ng-transclude` を持つことを意味しています。つまり、ディレクティブのコンポジションです。理論上はコンポーネントは末節のノードまで無限にネストすることができます。 ### Interpreter From aa7345def33688e178885d328de55706a741da97 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 15:48:35 +0900 Subject: [PATCH 19/27] Translate Interpreter --- README-ja-jp.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index ea0c4a6..c229c8c 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -26,7 +26,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [傍受フィルタ](#傍受フィルタ) * [ディレクティブ](#ディレクティブ-1) * [コンポジット](#コンポジット) - * [Interpreter](#interpreter) + * [インタープリタ](#インタープリタ) * [Template View](#template-view) * [Scope](#scope-1) * [Observer](#observer) @@ -662,32 +662,32 @@ myModule.directive('zippy', function () { 2番目のJavaScriptの例から、ディレクティブの `template` プロパティは `ng-transclude` ディレクティブが付加されたマークアップを見つけることができます。 `zippy` ディレクティブの中で別のディレクティブである `ng-transclude` を持つことを意味しています。つまり、ディレクティブのコンポジションです。理論上はコンポーネントは末節のノードまで無限にネストすることができます。 -### Interpreter +### インタープリタ ->In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence. +>コンピュータプログラミングではインタープリタ・パターンはある言語の文をどのように評価するかを決めるデザイン・パターンです。言語に特化したそれぞれのシンボル(オペレータであるかそうでないかは関係なく)に対する分類を持つというのが基本的な考え方です。文のシンタックス・ツリーはコンポジットパターンのインスタンスです。そして、それは分を評価(解釈)する際に使われます。 ![Interpreter](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/interpreter.svg "Fig. 6") -Behind its `$parse` service, AngularJS provides its own implementation of interpreter of a DSL (Domain Specific Language). The used DSL is simplified and modified version of JavaScript. -The main differences between the JavaScript expressions and AngularJS expressions that AngularJS expressions: +`$parse` サービスの背後では、AngularJSは独自のDSL(Domain Specific Language)記法のインタープリタを実装しています。DSLはシンプルに変更されたJavaScriptです。 +JavaScript記法とAngularJS機能の主な違いとして、AngularJS記法は: -- may contain filters with UNIX like pipe syntax -- don't throw any errors -- don't have any control flow statements (exceptions, loops, if statements although you can use the ternary operator) -- are evaluated in given context (the context of the current `$scope`) +- UNIX的なパイプ・シンタックスを含んでいること +- エラーを投げないこと +- コントロール・フロー文をもたないこと(オペレータは使えるが、例外、ループ、if文は持たない) +- 所与のコンテクスト内で評価されること(現在の `$scope` のコンテクスト) -Inside the `$parse` service are defined two main components: +`$parse` サービスのの内部では2つの主なコンポーネントが定義されています: ```JavaScript -//Responsible for converting given string into tokens +//与えられた文字列をトークンに変換する責務を追う var Lexer; -//Responsible for parsing the tokens and evaluating the expression +//トークンをパースして式を評価する責務を追う var Parser; ``` -Once given expression have been tokenized it is cached internally, because of performance concerns. +式がトークン化されると、パフォーマンスのために内部にキャッシュされます。 -The terminal expressions in the AngularJS DSL are defined as follows: +AngularJS DSLではオペレータは下記のように定義されています: ```JavaScript var OPERATORS = { @@ -720,14 +720,14 @@ var OPERATORS = { }; ``` -We can think of the function associated with each terminal as implementation of the `AbstractExpression`'s interface. +それぞれのオペレータに関連付けられた関数を `AbstractExpression` のインターフェイス実装と考えることができます。 -Each `Client` interprets given AngularJS expression in a specific context - specific scope. +それぞれの `Client` は与えられたAngularJSの式を固有のコンテキスト - 固有のスコープで解釈します。 -Few sample AngularJS expressions are: +AngularJSのサンプルの式です: ```JavaScript -// toUpperCase filter is applied to the result of the expression +// toUpperCase フィルタは式の結果に対して適用されます // (foo) ? bar : baz (foo) ? bar : baz | toUpperCase ``` From 42dcf3a17c0f9595c5c889b4b768d922acf48cba Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 16:08:49 +0900 Subject: [PATCH 20/27] Translate Template View --- README-ja-jp.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index c229c8c..8dedb4d 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -27,7 +27,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [ディレクティブ](#ディレクティブ-1) * [コンポジット](#コンポジット) * [インタープリタ](#インタープリタ) - * [Template View](#template-view) + * [テンプレート・ビュー](#テンプレート・ビュー) * [Scope](#scope-1) * [Observer](#observer) * [Chain of Responsibilities](#chain-of-responsibilities) @@ -732,20 +732,19 @@ AngularJSのサンプルの式です: (foo) ? bar : baz | toUpperCase ``` -#### Template View +#### テンプレート・ビュー -> Renders information into HTML by embedding markers in an HTML page. +> ページの中にマーカーを埋め込むことにより情報をHTMLにレンダーします。 ![Template View](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/template-view.svg "Fig. 8") -The dynamic page rendering is not that trivial thing. It is connected with a lot of string concatenations, manipulations and frustration. Far easier way to build your dynamic page is to write your markup and embed little expressions inside it, which are lately evaluated in given context and so the whole template is being compiled to its end format. In our case this format is going to be HTML (or even DOM). This is exactly what the template engines do - they take given DSL, evaluate it in the appropriate context and then turn it into its end format. +動的なページのレンダリングはそんなに簡単なことではありません。たくさんの文字列の連結や操作やいらいらと結びついています。動的なページを構築するとても簡単な方法はマークアップとちょっとした式をページに書き込んでしまうことです。それはコンテキスト内で評価されテンプレートは最終的な形にコンパイルされます。今回そのフォーマットはHTML(DOM)になります。これはまさにテンプレート・エンジンそのものです - 与えられたDSLを適切なコンテキスト内で評価し、最終的な形に変換します。 -Templates are very commonly used especially in the back-end. -For example, you can embed PHP code inside HTML and create a dynamic page, you can use Smarty or you can use eRuby with Ruby in order to embed Ruby code inside your static pages. +テンプレートはバックエンド環境ではよく使われています。例えば、Smartyを使ってPHPコードをHTMLに埋め込んで動的なページを作ることができます。RubyではeRubyを使って静的なページにコードを埋め込むことができます。 -For JavaScript there are plenty of template engines, such as mustache.js, handlebars, etc. Most of these engines manipulate the template as a string. The template could be located in different places - as static file, which is fetched with AJAX, as `script` embedded inside your view or even inlined into your JavaScript. +JavaScriptにはmustache.jsやhandlebarsなどたくさんのテンプレートエンジンがあります。これらのエンジンの殆どは文字列としてテンプレートを操作します。テンプレートは別の場所に静的ファイルとして置いてAJAXで取得します。また、 `script` としてビューやJavaScriptの中に埋め込まれます。 -For example: +例えばこのように: ```html ``` -The template engine turns this string into DOM elements by compiling it within a given context. This way all the expressions embedded in the markup are evaluated and replaced by their value. +テンプレートエンジンはコンテキストの中でコンパイルすることにより文字列をDOM要素に変換します。このように全てのマークアップに埋め込まれている全ての式は評価されそれらの値に変換されます。 -For example if we evaluate the template above in the context of the following object: `{ names: ['foo', 'bar', 'baz'] }`, so we will get: +例えば、上記のテンプレートを次のオブジェクト・コンテキスト `{ names: ['foo', 'bar', 'baz'] }` の状態で評価するとこのような結果を得ることができます: ```html

Names

@@ -767,10 +766,11 @@ For example if we evaluate the template above in the context of the following ob baz ``` -AngularJS templates are actually HTML, they are not in an intermediate format like the traditional templates are. -What AngularJS compiler does is to traverse the DOM tree and look for already known directives (elements, attributes, classes or even comments). When AngularJS finds any of these directives it invokes the logic associated with them, which may involve evaluation of different expressions in the context of the current scope. +AngularJSのテンプレートは本物のHTMLです。同等的なテンプレートエンジンがするような中間フォーマットではありません。 -For example: +AngularJSコンパイラはDOMツリーを行き来し、既に知っているディレクティブ(要素、アトリビュート、クラス、コメント)を探すことです。AngularJSがこれらのディレクティブを見つけると、それと関連付けられたロジックを実行します。現在のスコープ・コンテキストの中で別の式を評価することもあります。 + +例えば: ```html
    @@ -778,14 +778,13 @@ For example:
``` -in the context of the scope: +スコープのコンテキストの中は: ```javascript $scope.names = ['foo', 'bar', 'baz']; ``` -will produce the same result as the one above. The main difference here is that the template is not wrapped inside a `script` tag but is HTML instead. - +これは、上記のものと同じ結果を出力します。ここでの主な違いはテンプレートが `script` にラップされていず、HTMLのままであるということです。 ### Scope From 5331f02a1a8586a42d7211e39fcaf634915118d2 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 16:58:09 +0900 Subject: [PATCH 21/27] Translate Observer --- README-ja-jp.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 8dedb4d..84d9d9f 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -28,8 +28,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [コンポジット](#コンポジット) * [インタープリタ](#インタープリタ) * [テンプレート・ビュー](#テンプレート・ビュー) - * [Scope](#scope-1) - * [Observer](#observer) + * [スコープ](#スコープ-1) + * [オブザーバ](#オブザーバ) * [Chain of Responsibilities](#chain-of-responsibilities) * [Command](#command) * [Controller](#controller-1) @@ -786,30 +786,30 @@ $scope.names = ['foo', 'bar', 'baz']; これは、上記のものと同じ結果を出力します。ここでの主な違いはテンプレートが `script` にラップされていず、HTMLのままであるということです。 -### Scope +### スコープ -#### Observer +#### オブザーバ ->The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. +>オブザーバはサブジェクトと呼ばれるオブジェクトが依存しているオブザーバのリストを管理し、変更があったらオブザーバのメソッドを呼び出すことで通知するデザイン・パターンです。主に分散したイベント・ハンドリング・システムで利用されます。 ![Observer](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/observer.svg "Fig. 7") -There are two basic ways of communication between the scopes in an AngularJS application. The first one is calling methods of parent scope by a child scope. This is possible since the child scope inherits prototypically by its parent, as mentioned above (see [Scope](#scope)). This allows communication in a single direction - child to parent. Some times it is necessary to call method of given child scope or notify it about a triggered event in the context of the parent scope. AngularJS provides built-in observer pattern, which allows this. Another possible use case, of the observer pattern, is when multiple scopes are interested in given event but the scope, in which context the event is triggered, is not aware of them. This allows decoupling between the different scopes, non of the scopes should be aware of the rest of the scopes. +AngularJSアプリケーションのスコープ間では主に2つの基本的なやりとりの方式があります。一つ目は子スコープが親スコープのメソッドを呼び出すことです。子スコープは親スコープをプロトタイプ継承しているのでこれが可能になります(参考: [スコープ](#スコープ) )。これは子から親への1方向のコミュニケーションです。時に、親スコープから子スコープのメソッドを呼び出したり、子スコープにイベントの通知を送りたい時があります。AngularJSはこれを実現するための組み込みのオブザーバ・パターンを用意しています。オブザーバ・パターンが必要とされる別のケースとして、複数のスコープがあるイベントに関心があるものの、そのイベントは別スコープにあるため気づけないというものがあります。別々のスコープ間の分離が行われているため、別のスコーぷの変更に気づくことができません。 -Each AngularJS scope has public methods called `$on`, `$emit` and `$broadcast`. The method `$on` accepts topic as first argument and callback as second. We can think of the callback as an observer - an object, which implements the `Observer` interface (in JavaScript the functions are first-class, so we can provide only implementation of the `notify` method): +それぞれのAngularJSのスコープは `$on` 、 `$emit` 、 `$broadcast` と呼ばれるパブリック・メソッドを持っています。 `$on` メソッドは最初の引数として関心のある項目をとり、2つ目の引数としてコールバックをとります。このコールバックを `Observer` インターフェイスが実装されたオブザーバと考えることができます(JavaScriptでは関数は第一級オブジェクトなので、ただ、 `notify` メソッドを実装すればよいだけです): ```JavaScript function ExampleCtrl($scope) { $scope.$on('event-name', function handler() { - //body + //内容 }); } ``` -In this way the current scope "subscribes" to events of type `event-name`. When `event-name` is triggered in any parent or child scope of the given one, `handler` would be called. +この方法で、現在のスコープは `event-name` のイベントを登録することができます。 `event-name` が親スコープや子スコープで実行された場合、 `handler` が呼ばれます。 -The methods `$emit` and `$broadcast` are used for triggering events respectively upwards and downwards through the scope chain. -For example: +`$emit` メソッドと `$broadcast` メソッドはそれぞれスコープチェーンの上方向と下方向にイベントを伝播します。 +例えば: ```JavaScript function ExampleCtrl($scope) { @@ -817,12 +817,12 @@ function ExampleCtrl($scope) { } ``` -The scope in the example above, triggers the event `event-name` to all scopes upwards. This means that each of the parent scopes of the given one, which are subscribed to the event `event-name`, would be notified and their handler callback will be invoked. +上記のスコープは、 `event-name` を上方向に伝播します。 `event-name` を登録している全ての親スコープは通知を受け、登録されているコールバックが実行されます。 -Analogical is the case when the method `$broadcast` is called. The only difference is that the event would be transmitted downwards - to all children scopes. -Each scope can subscribe to any event with multiple callbacks (i.e. it can associate multiple observers to given event). +`$broadcast` が呼ばれたときも同様です。違いは、イベントの伝播が下方向(すべての子スコープ)に行くということです。 +それぞれのスコープが複数のコールバックを登録することができます(複数のオブザーバと関連することができます)。 -In the JavaScript community this pattern is better known as publish/subscribe. +JavaScriptコミュニティではこのパターンはパブリッシュ/サブスクライブとして知られています。 #### Chain of Responsibilities From b504e5ad1986bb1c4764ec1d45dbcd7b98eaa0bb Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 17:15:24 +0900 Subject: [PATCH 22/27] Translate Chain of Responsibilities --- README-ja-jp.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 84d9d9f..50faede 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -30,7 +30,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [テンプレート・ビュー](#テンプレート・ビュー) * [スコープ](#スコープ-1) * [オブザーバ](#オブザーバ) - * [Chain of Responsibilities](#chain-of-responsibilities) + * [チェーン・オブ・レスポンシビリティ](#チェーン・オブ・レスポンシビリティ) * [Command](#command) * [Controller](#controller-1) * [Page Controller](#page-controller) @@ -824,22 +824,24 @@ function ExampleCtrl($scope) { JavaScriptコミュニティではこのパターンはパブリッシュ/サブスクライブとして知られています。 -#### Chain of Responsibilities +#### チェーン・オブ・レスポンシビリティ ->The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain. +>チェーン・オブ・レスポンシビリティ・パターンはコマンド・オブジェクトと続く一連の処理オブジェクトからなるデザイン・パターンです。それぞれの処理オブジェクトは処理が可能なコマンド・オブジェクトを規定するロジックを持っています。残りの部分は次の処理オブジェクトに連鎖的に渡されます。新しい処理オブジェクトを連らの末尾に追加するメカニズムも存在しています。 ![Chain of Responsibilities](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/chain-of-responsibilities.svg "Fig. 5") -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. +上述のようにAngularJSアプリケーションのスコープはスコープ・チェーンという階層構造を持っています。いくつかのスコープは "分離" しています。 "分離" とは親スコープからプロトタイプ継承していないということを意味しています。しかし、親スコープへは `$parent` プロパティでアクセスできます。 -When `$emit` or `$broadcast` are called we can think of the scope chain as event bus, or even more accurately chain of responsibilities. Once the event is triggered it is emitted downwards or upwards (depending on the method, which was called). Each subsequent scope may: +`$emit` や `$broadcast` が呼ばれた時、スコープ・チェーンをイベント・バスとして、またはより正確に責任の連鎖考えることができます。イベントが起こると、それは(呼ばれたメソッドに応じて)下方向に、または、上方向に伝播します。続くスコープは: -- Handle the event and pass it to the next scope in the chain -- Handle the event and stop its propagation -- Pass the event to the next scope in the chain without handling it -- Stop the event propagation without handling it +- イベントを処理し、次のスコープに渡す +- イベントを処理し、そこで伝播を止める +- イベントを処理せず、次のスコープに渡す +- イベントを処理せず、そこで伝播を止める -In the example bellow you can see an example in which `ChildCtrl` triggers an event, which is propagated upwards through the scope chain. In the case above each of the parent scopes (the one used in `ParentCtrl` and the one used in `MainCtrl`) are going to handle the event by logging into the console: `"foo received"`. If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. +下の例では `ChildCtrl` がイベントを発し、スコープ・チェーンの上方向に伝播させるところを確認できます。 親のスコープ( `ParentCtrl` と `MainCtrl` )はコンソールにログを出します: `"foo received"` 。スコープがイベントの終着地点である場合は、イベント・オブジェクトの `stopPropagation` メソッドを呼び出し、コールバックに渡します。 + +If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. ```JavaScript myModule.controller('MainCtrl', function ($scope) { @@ -859,7 +861,7 @@ myModule.controller('ChildCtrl', function ($scope) { }); ``` -The different handlers from the UML diagram above are the different scopes, injected to the controllers. +上記UMLダイアグラムの別々のハンドラーはそれぞれコントローラに注入された別々のスコープです。 #### Command From e7bbdca45971ccece7c4e0b4f167d719265ac15c Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 17:33:18 +0900 Subject: [PATCH 23/27] Translate Command --- README-ja-jp.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 50faede..6068039 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -31,7 +31,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [スコープ](#スコープ-1) * [オブザーバ](#オブザーバ) * [チェーン・オブ・レスポンシビリティ](#チェーン・オブ・レスポンシビリティ) - * [Command](#command) + * [コマンド](#コマンド) * [Controller](#controller-1) * [Page Controller](#page-controller) * [Others](#others) @@ -841,8 +841,6 @@ JavaScriptコミュニティではこのパターンはパブリッシュ/サ 下の例では `ChildCtrl` がイベントを発し、スコープ・チェーンの上方向に伝播させるところを確認できます。 親のスコープ( `ParentCtrl` と `MainCtrl` )はコンソールにログを出します: `"foo received"` 。スコープがイベントの終着地点である場合は、イベント・オブジェクトの `stopPropagation` メソッドを呼び出し、コールバックに渡します。 -If any of the scopes should be considered as final destination it can call the method `stopPropagation` of the event object, passed to the callback. - ```JavaScript myModule.controller('MainCtrl', function ($scope) { $scope.$on('foo', function () { @@ -863,31 +861,31 @@ myModule.controller('ChildCtrl', function ($scope) { 上記UMLダイアグラムの別々のハンドラーはそれぞれコントローラに注入された別々のスコープです。 -#### Command +#### コマンド ->In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters. +>オブジェクト指向プログラミングでは、コマンド・パターンは後々メソッドの呼び出しをする際に必要となる情報をカプセル化した振る舞いのデザイン・パターンです。この情報はメソッド名、メソッドやメソッドパラメータとして利用される値を持つオブジェクトを含みます。 ![Command](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/command.svg "Fig. 11") -Before continuing with the application of the command pattern lets describe how AngularJS implements data binding. +コマンド・パターンのアプリケーションに進む前に、AngularJSではどのようにデータ・バインディングをしているか説明しましょう。 -When we want to bind our model to the view we use the directives `ng-bind` (for single-way data binding) and `ng-model` (for two-way data binding). For example, if we want each change in the model `foo` to reflect the view we can: +モデルとビューをバインドしたいとき、 `ng-bind` (1方向データ・バインディング)や `ng-model` (双方向データ・バインディング)を使います。例えば、 `foo` モデルの変更をビューに反映させたいとき、このように書くことができます: ```html ``` -Now each time we change the value of `foo` the inner text of the span will be changed. We can achieve the same effect with more complex AngularJS expressions, like: +`foo` が変更される度に、spanのテキストは変わります。もう少し複雑なAngularJSの式を書くこともできます: ```html ``` -In the example above the value of the span will be the concatenated uppercased value of `foo` and `bar`. What happens behind the scene? +このケースでは、spanは大文字化した `foo` と `bar` の組み合わせとなります。裏では何が起こっているのでしょうか? -Each `$scope` has method called `$watch`. When the AngularJS compiler find the directive `ng-bind` it creates a new watcher of the expression `foo + ' ' + bar | uppercase`, i.e. `$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });`. The callback will be triggered each time the value of the expression change. In the current case the callback will update the value of the span. +`$scope` は `$watch` と呼ばれるメソッドを持っています。AngularJSコンパイラが `ng-bind` を見つけると、 `foo + ' ' + bar | uppercase` 式のwatcherを生成します。具体的には、 `$scope.$watch("foo + ' ' + bar | uppercase", function () { /* body */ });` です。式の値が変わる度に、コールバックが呼ばれます。今回のケースではspanを更新します。 -Here are the first a couple of lines of the implementation of `$watch`: +これは、 `$watch` の実装の最初の行です: ```javascript $watch: function(watchExp, listener, objectEquality) { @@ -904,7 +902,7 @@ $watch: function(watchExp, listener, objectEquality) { //... ``` -We can think of the `watcher` object as a command. The expression of the command is being evaluated on each [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) loop. Once AngularJS detects change in the expression, it invokes the `listener` function. The `watcher` command encapsulates the whole information required for watching given expression and delegates the execution of the command to the `listener` (the actual receiver). We can think of the `$scope` as the command's `Client` and the `$digest` loop as the command's `Invoker`. +`watcher` オブジェクトをコマンドと考えることができます。コマンドの式は、 [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) ループの度に評価されます.AngularJSが式の変更を検知すると、 `listner` 関数を呼びます。 `watcher` コマンドは式の変更に必要な情報をカプセル化しています。そして、コマンドの実行を `listner` (実際のレシーバ)に委譲します。 `$scope` をコマンドの `Client` 、 `$digest` ループをコマンドの `Invoker` と考えることができます。 ### Controllers From abb6be8810ba0117c3498fb50e1cbdef68cccf6f Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 17:52:22 +0900 Subject: [PATCH 24/27] Translate Page Controller --- README-ja-jp.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 6068039..b79b618 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -32,8 +32,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [オブザーバ](#オブザーバ) * [チェーン・オブ・レスポンシビリティ](#チェーン・オブ・レスポンシビリティ) * [コマンド](#コマンド) - * [Controller](#controller-1) - * [Page Controller](#page-controller) + * [コントローラ](#コントローラ-1) + * [ページ・コントローラ](#ページ・コントローラ) * [Others](#others) * [Module Pattern](#module-pattern) * [Data Mapper](#data-mapper) @@ -904,24 +904,24 @@ $watch: function(watchExp, listener, objectEquality) { `watcher` オブジェクトをコマンドと考えることができます。コマンドの式は、 [`"$digest"`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) ループの度に評価されます.AngularJSが式の変更を検知すると、 `listner` 関数を呼びます。 `watcher` コマンドは式の変更に必要な情報をカプセル化しています。そして、コマンドの実行を `listner` (実際のレシーバ)に委譲します。 `$scope` をコマンドの `Client` 、 `$digest` ループをコマンドの `Invoker` と考えることができます。 -### Controllers +### コントローラ -#### Page Controller +#### ページ・コントローラ ->An object that handles a request for a specific page or action on a Web site. Martin Fowler +>ウェブサイトの特定のページやアクションのリクエストを扱うオブジェクト。 Martin Fowler ![Page Controller](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/page-controller.svg "Fig. 8") -According to [4](#references) the page controller: +[4](#references) によると、ページ・コントローラは: ->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`. +ページ毎にたくさんの似たような振る舞いがある(フッタやヘッダのレンダリング、ユーザ・セッションの扱い)ので、ページコントローラは階層構造を持っています。AngularJSでは責任の制限されたコントローラを持っています。このコントローラは `$route` や `$state` サービスがあるため、ユーザのリクエストを受け付けません。また、ページのレンダリングは `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. +ページ・コントローラと同じようにAngularJSのコントローラはユーザのインタラクションを扱いますし、モデルを提供して更新します。モデルはスコープに付けられた場合、ビューに露出します。ユーザのアクションによってビューから呼び出されるメソッドは既にスコープに付けられたものです。ページ・コントローラとAngularJSのコントローラのもう一つの類似点は、階層構造です。これはスコーぷの階層構造に対応しています。このやりかたで、共通のアクションはベース・コントローラに分離することができます。 -The controllers in AngularJS are quite similar to the code-behind in ASP.NET WebForms, since their responsibilities almost overlap. -Here is an example hierarchy between few controllers: +AngularJSのコントローラはASP.NET WebFormsのコードにとても良く似ています。これらの責任はほぼ重なります。 +いくつかのコントローラの階層構造の例です: ```HTML @@ -952,9 +952,9 @@ 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. +`ChildCtrl` は `"Click"` ラベルのあるボタンをクリックするアクションを扱い、また、モデルをスコープに取り付けビューに露出させる責任があります。 ### Others From 6b2bc97519aeb9b47e3639d6ee472eb7bbcace2b Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 18:06:01 +0900 Subject: [PATCH 25/27] Translate Module Pattern --- README-ja-jp.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index b79b618..9972f13 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -34,8 +34,8 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [コマンド](#コマンド) * [コントローラ](#コントローラ-1) * [ページ・コントローラ](#ページ・コントローラ) - * [Others](#others) - * [Module Pattern](#module-pattern) + * [その他](#その他) + * [モジュール・パターン](#モジュール・パターン) * [Data Mapper](#data-mapper) * [References](#references) @@ -956,13 +956,13 @@ function ChildCtrl($scope, User) { `ChildCtrl` は `"Click"` ラベルのあるボタンをクリックするアクションを扱い、また、モデルをスコープに取り付けビューに露出させる責任があります。 -### Others +### その他 -#### Module Pattern +#### モジュール・パターン -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. +これは実際にはGang of FourやP of EAAのデザイン・パターンではありません。これはカプセル化とプライバシーを目的とした伝統的なJavaScriptのパターンです。 -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: +モジュール・パターンを利用することで、JavaScriptの関数スコープにおけるプライバシーを達成することができます。それぞれのモジュールは関数のローカルスコープの中に隠されたゼロかプリミティブな番号を持っています。この関数は与えられたモジュールのパブリックAPIを出力するオブジェクトを返します。 ```javascript var Page = (function () { @@ -985,23 +985,23 @@ var Page = (function () { }()); ``` -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. +上記の例は2つのメソッド( `setTitle` と `getTitle` )を持ったオブジェクトを返すIIFE(Immediately-Invoked Function Expression)を持っています。返却されたオブジェクトは、 `Page` 変数に関連付けられています。 -In this case the user of the `Page` object doesn't has direct access to the `title` variable, which is defined inside the local scope of the IIFE. +このケースでは `Page` オブジェクトのユーザは `title` に直接アクセスするすべを持っていません。 `title` はIIFEのローカルスコープの中に定義されているからです。 -The module pattern is very useful when defining services in AngularJS. Using this pattern we can simulate (and actually achieve) privacy: +モジュール・パターンはAngularJSでサービスを定義する際にとても有益です。このパターンを使うことで、プライバシーをシミュレート(事実上達成)することができます: ```javascript app.factory('foo', function () { function privateMember() { - //body... + //内容... } function publicMember() { - //body... + //内容... privateMember(); - //body + //内容 } return { @@ -1010,6 +1010,8 @@ app.factory('foo', function () { }); ``` +`foo` を別のコンポーネントに注入すると、パブリック・メソッドだけにアクセスしてプライベートメソッドを呼ぶ必要がありません。この方法は再利用可能なライブラリを作成する際にとても強力なたすけになります。 + 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. ### Data Mapper From 7d3709cd6584f58e78ada4237ec363318a864162 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 18:26:51 +0900 Subject: [PATCH 26/27] Translate Data Mapper --- README-ja-jp.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index 9972f13..d7366fc 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -36,7 +36,7 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [ページ・コントローラ](#ページ・コントローラ) * [その他](#その他) * [モジュール・パターン](#モジュール・パターン) - * [Data Mapper](#data-mapper) + * [データ・マッパ](#データ・マッパ) * [References](#references) @@ -1014,28 +1014,28 @@ app.factory('foo', function () { 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. -### Data Mapper +### データ・マッパ ->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. +>データ・マッパは永続データ・ストア(リレーショナル・データベースがよく使われる)とイン・メモリ・データ・リプリゼンテーション(ドメイン・レイヤ)との双方向のやりとりをするためのデータ・アクセス・レイヤです。このパターンの目的はイン・メモリ・リプリゼンテーションと永続データ・ストアとマッパそれ自体をそれぞれ独立させることです。 ![Data Mapper](https://rawgit.com/mgechev/angularjs-in-patterns/master/images/data-mapper.svg "Fig. 10") -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.). +上記の図が示すように、データ・マッパは永続データ・ストアとイン・メモリ・データ・リプレゼンテーションの双方向通信をするために利用されています。普通、AngluarJSアプリケーションでは、サーバ・サイドの言語(Ruby, PHP, Java, JavaScriptなど)で書かれたAPIサーバとやりとりします。 -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. +普通、RESTful APIを持っている場合、 `$resource` がアクティブ・レコードのような形でその通信をサポートします。しかし、アプリケーションによってはサーバから返されるデータがフロントエンドで利用するには適切で無いフォーマットで返されることもあります。 -For instance, lets assume we have application in which each user has: +例えば、ユーザが次の要素を持つと想定してみてください: -- name -- address -- list of friends +- 名前 +- 住所 +- 友達リスト -And our API has the methods: +そして、APIが次のメソッドを持つとします: -- `GET /user/:id` - returns the user's name and the address of given user -- `GET /friends/:id` - returns the list of friends of given user +- `GET /user/:id` - ユーザの名前と住所を返します +- `GET /friends/:id` - ユーザの友達リストを返します -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: +解決策としては2つの別々のサービスを作ることです。恐らくもう少し有効な解決策は、 `User` という1つのサービスがあった場合に、ユーザをリクエストした際に、ユーザの友達リストも一緒に読み込むことです。 ```javascript app.factory('User', function ($q) { @@ -1058,9 +1058,9 @@ app.factory('User', function ($q) { }); ``` -This way we create pseudo-data mapper, which adapts our API according to the SPA requirements. +この方法でSPAの要求に応じてAPIを適用させた仮のデータ・マッパを作ることができます。 -We can use the `User` service by: +`User` サービスはこのように利用することができます: ```javascript function MainCtrl($scope, User) { @@ -1071,7 +1071,7 @@ function MainCtrl($scope, User) { } ``` -And the following partial: +そして、パーシャルがこちらです: ```html
From f372dddfd8aca3875ff8b057412bc910e6f3f0c9 Mon Sep 17 00:00:00 2001 From: Naoki Morita Date: Sun, 29 Mar 2015 18:34:01 +0900 Subject: [PATCH 27/27] Remove dot in Table of Contents to make anchor work --- README-ja-jp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README-ja-jp.md b/README-ja-jp.md index d7366fc..e41bc79 100644 --- a/README-ja-jp.md +++ b/README-ja-jp.md @@ -18,25 +18,25 @@ _このドキュメントは[AngularJS in Patterns](https://github.com/mgechev/a * [AngularJSのパターン](#AngularJSのパターン) * [サービス](#サービス-1) * [シングルトン](#シングルトン) - * [ファクトリ・メソッド](#ファクトリ・メソッド) + * [ファクトリ・メソッド](#ファクトリメソッド) * [デコレータ](#デコレータ) * [ファサード](#ファサード) * [プロキシ](#プロキシ) - * [アクティブ・レコード](#アクティブ・レコード) + * [アクティブ・レコード](#アクティブレコード) * [傍受フィルタ](#傍受フィルタ) * [ディレクティブ](#ディレクティブ-1) * [コンポジット](#コンポジット) * [インタープリタ](#インタープリタ) - * [テンプレート・ビュー](#テンプレート・ビュー) + * [テンプレート・ビュー](#テンプレートビュー) * [スコープ](#スコープ-1) * [オブザーバ](#オブザーバ) - * [チェーン・オブ・レスポンシビリティ](#チェーン・オブ・レスポンシビリティ) + * [チェーン・オブ・レスポンシビリティ](#チェーンオブレスポンシビリティ) * [コマンド](#コマンド) * [コントローラ](#コントローラ-1) - * [ページ・コントローラ](#ページ・コントローラ) + * [ページ・コントローラ](#ページコントローラ) * [その他](#その他) - * [モジュール・パターン](#モジュール・パターン) - * [データ・マッパ](#データ・マッパ) + * [モジュール・パターン](#モジュールパターン) + * [データ・マッパ](#データマッパ) * [References](#references)