【AngularJS】クリックした要素を$eventオブジェクトから取得する。

angularで要素を取得したかった時に困ったのでメモ。

ng-clickディレクティブで実行する関数に$eventを渡してやる。

<ANY
    ng-click="click($event)"
></ANY>

コントローラー側で受け取ったオブジェクトの「target」要素を参照してやればOK。

$scope.click = function($event) {
	console.log($event.target);
}

あとは煮るなり焼くなり好きにすればOK。

 

【UnderscoreJS】RestAPIから取得したJSONなどの中から特定のIDを持つものを削除する。

例えば下記のようなjsonオブジェクトでIDが5の要素のみ削除したいといった場合。

var oldJson = [
    {id: 1, name: 'taro', age: 14},
    {id: 2, name: 'yamada', age: 15},
    {id: 3, name: 'emily', age: 16},
    {id: 4, name: 'bob', age: 17},
    {id: 5, name: 'hanako', age: 18}
];

_.filter()メソッドを用いると便利。

var newJson = _.filter(oldJson, , function(data) {
    return data.id != 5;
})

これでID5のオブジェクトを削除することが出来る。

 

【AngularJS】$resourceにPATCHメソッドを実装する。

その他のメソッドと同様、下記のように実装すればOK。

coreCtrls.factory('hoge', ['$resource', function($resource) {
    return $resource(location.pathname + 'api/hoge/:id', {
        id: '@id'
    }, {
        'patch': {
            method: 'PATCH'
        }
    });
}])

 

【Symfony2.3】FOSRestBundleのserializerで除外変数を指定する。

エンティティ内のジョインしているフィールドでシリアライズしたくない項目がある場合に便利。

use JMS\Serializer\Annotation as JMS;

class Report
{
    /**
     * @JMS\Exclude
     */
    protected $categories;
}

無視したい変数のアノテーションで「@JMS\Exclude」と指定してやればOK。

その他グルーピングなども指定出来る模様。詳細は下記。

http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies

 

【AngularJS】独自のページネーションサービスを実装する。

してみた。

下記URLのソースを参考に作成。

https://github.com/svileng/ng-simplePagination/blob/master/simplePagination.js
https://github.com/cakephp/cakephp/blob/master/lib/Cake/View/Helper/PaginatorHelper.php

これはかなり使いやすい。

"use strict";

var paginationModule = angular.module('ngPagination', []);

/**
 * usage
 * 
 * - main module
 * 
 * var app = angular.module('app', [
 *     'ngPagination'
 * ]);
 * 
 * 
 * - controller
 * 
 * @recipe     ng-resource object
 * @Pagination Pagination object
 * 
 * app.controller('exampleCtrl'. function($scope, recipe, Pagination) {
 *     $scope.pagination = Pagination.getNew(10, 6); // (parPage, modules)
 *     $scope.lists = recipe.query(function() {
 *         $scope.pagination.numPages = Math.ceil($scope.lists.length / $scope.pagination.perPage);
 *     });
 * });
 * 
 * 
 * - view (template)
 * 
 * - pagination element
 *  
 * <ul>
 *     <li><a href="" ng-click="pagination.firstPage()" ng-hide="pagination.page == 0">??</a></li>
 *     <li><a href="" ng-click="pagination.prevPage()" ng-hide="pagination.page == 0">?</a></li>
 *     <li><a href="" ng-show="pagination.beforeEllipsis">...</a></li>
 *     <li ng-repeat="n in [] | range: pagination" ng-class="{active: n == pagination.page}"><a href="" ng-click="pagination.toPageId(n)">{{n + 1}}</a></li>
 *     <li><a href="" ng-show="pagination.afterEllipsis">...</a></li>
 *     <li><a href="" ng-click="pagination.nextPage()" ng-hide="pagination.page + 1 >= pagination.numPages">?</a></li>
 *     <li><a href="" ng-click="pagination.lastPage()" ng-hide="pagination.page + 1 >= pagination.numPages">??</a></li>
 * </ul>
 * 
 * - angular repeater
 * 
 * <ANY
 *     ng-repeat="data in lists | startFrom: pagination.page * pagination.perPage | limitTo: pagination.perPage"
 * >
 * ...
 * </ANY>
 * 
 */
paginationModule.factory('$pagination', function() {

    var pagination = {};
  
    pagination.getNew = function(perPage, modules) {

        perPage = perPage === undefined ? 5 : perPage;
        modules = modules === undefined ? 4 : modules;
    
        var paginator = {
            numPages: 1,
            perPage: perPage,
            page: 0,
            modules: modules,
            beforeEllipsis: false,
            afterEllipsis: false
        };
    
        paginator.prevPage = function() {
            if (paginator.page > 0) {
                paginator.page -= 1;
            }
        };
    
        paginator.nextPage = function() {
            if (paginator.page < paginator.numPages - 1) {
                paginator.page += 1;
            }
        };
        
        paginator.firstPage = function() {
            if (paginator.page > 0) {
                paginator.page = 0;
            }
        };
        
        paginator.lastPage = function() {
            if (paginator.page < paginator.numPages - 1) {
                paginator.page = paginator.numPages - 1;
            }
        };
    
        paginator.toPageId = function(id) {
            if (id >= 0 && id <= paginator.numPages - 1) {
                paginator.page = id;
            }
        };
    
        return paginator;
    };

    return pagination;
});

paginationModule.filter('startFrom', function() {
    return function(input, start) {
        if (input === undefined) {
            return input;
        } else {
            return input.slice(+start);
        }
    };
});

/**
 * @input      ng-repeat elements
 * @pagination pagination object
 */
paginationModule.filter('range', function() {
    return function(input, pagination) {
        
        var pageCount = pagination.numPages,
            page = pagination.page,
            modules = pagination.modules
        ;
        
        pageCount = parseInt(pageCount);
        
        if (modules && pageCount > modules) {
            
            page += 1;
            
            if (Math.ceil(modules / 2) + 1 < page) {
                pagination.beforeEllipsis = true;
            } else {
                pagination.beforeEllipsis = false;
            }
            
            if (pageCount - Math.floor(modules / 2) - 1 < page) {
                pagination.afterEllipsis = false;
            } else {
                pagination.afterEllipsis = true;
            }
            
            var half = parseInt(modules / 2, 10);
            var end = page + half;
            
            if (end > pageCount) {
                end = pageCount;
            }
            
            var start = page - (modules - (end - page));
            if (start <= 1) {
                start = 1;
                end = page + (modules - page) + 1;
            }
            
            for (var i = start; i < page; i++) {
                input.push(i - 1);
            }
            
            input.push(page - 1);
            
            start = page + 1;
            for (var i = start; i < end; i++) {
                input.push(i - 1);
            }
            
            if (end != page) {
                input.push(i - 1);
            }
            
        } else {

            pagination.beforeEllipsis = false;
            pagination.afterEllipsis = false;
            
            for (var i = 0; i < pageCount; i++) {
                input.push(i);
            }
            
        }
        
        return input;
    };
});

 

【AngularJS】ng-viewで読み込んだビューがスクロール出来ない。

ことがある。

調べたらng-viewディレクティブにautoscroll属性を追加してやることで幸せになれる模様??

<div ng-view autoscroll></div>

 

【Symfony2.3】双方向Many-To-Manyの公式リファレンス。

参照する機会が多いので自分用にペタリ。

http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional

 

【Symfony2.3】Doctrine2のリレーションに関するメモ。

リレーションに関する解説としてとても参考になるページをみつけたのでペタリ。

http://www.exgear.jp/blog/2010/10/doctrine_association/

なかなか日本語の文献が少ないから、初学者にとってはありたがい。