2016年4月29日 星期五

[產品管理] MVP的概念

在這個凡事講求敏捷的時代, MVP的概念容易理解,實踐起來卻是困難。

老闆和客戶都想要完美和完整的功能,如何抓大放小,以及在成本、時間和品質的平衡上,就是專業經理人的經驗和價值。

我推薦以下這本書籍:
「成長駭客:未來十年最被需要的新型人才,用低成本的創意思考和分析技術,讓創業公司的用戶、流量與營收成長翻倍」


(圖片來源:博客來)



書裡面有談論到MVP的概念,也加入許多成功和失敗的案例可供參考。


另外底下這篇文章用漫畫解釋MVP的概念和重要性的文章,也相當有趣和容易理解 :)



[AngularJS] Select list directive

 AngularJS   Directive  



▌Background


Here is the sample of creating select list directive, which is binding the data source from Web Api.






Related article




Implement


$http factory

var app = angular.module('sexapp', ['app'])
.factory('SexFactory', function ($http, RestfulUriFactory) {


    var factory = {};

    //Get an Agent
    factory.GetAll =
        function (encryptId) {

            var getUri = RestfulUriFactory.GET_ALL_SEX_URI;

            return $http.get(getUri).error(function (status, headers, config) {
                console.log(status, headers, config);
            }).then(function (response) {
                return response;
            }).catch(function (e) {
                throw e;
            });
        };

    return factory;

});


Directive

angular.module('directive-sex-app', ['sexapp'])
.factory('SexQueryFactory', function ($q, RestfulUriFactory, SexFactory) {

        var factory = {};

        factory.GetAll = function () {

            var getAllJob = $q.defer();
            var getAllJobPromise = getAllJob.promise;

            var getPromise = SexFactory.GetAll();

            getPromise.then(function (response) {

                getAllJob.resolve(response.data);
            });

            return getAllJobPromise;
        }

        return factory;
})
.directive('sex', function (SexQueryFactory) {
    return {
        scope: true,
        //return trmplate
        template: '<select class="form-control" ng-model="item.Sex" ng-options="option.Id as option.Name for option in SexOptions track by option.Id" />',
        link: function ($scope) {

        },
        controller: function ($scope, $element) {

            var getAllSexPromise = SexQueryFactory.GetAll();

            getAllSexPromise.then(function (data) {
                $scope.SexOptions = data;
            });
        }
    }
});

In directive, use the parameter : template, to create a select list html with ngModel.
The select list’s data source will be loaded thru the $http factory in the previous step.

It’s done, we can use the directive now.


HTML

<div class="col-md-6" sex>
</div>






Reference





2016年4月27日 星期三

[AngularJS] Create directive for reusable elements and behavior

 AngularJS   Directive  


▌Introduction


What are directive?

Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children. - from docs.angularjs.org



▌Background


There are two or more pages that contain the same elements and behavior on them. For example, the following 2 textboxes and checkbox appear in multiple pages, and we would like to make the HTML and javascript reusable.








Implement : Create reusable directive



HTML

<div class="form-horizontal" ng-app="app" ng-controller="CreateCtrl">
<div class="form-group">
    <label class="control-label col-md-2" for="EnabledOn">啟用日期</label>
    <div class="col-md-10">
        <input type="datetime" enabledon ng-model="EnabledOn"/>
    </div>
</div>

<div class="form-group">
    <label class="control-label col-md-2">停用日期</label>
    <div  class="col-md-10">
        <table width="100%">
            <tr>
                <td>
                    <input type="datetime" disabledon ng-disabled="disabledDisabledOn" ng-model="DisabledOn" />
                </td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox" ng-model="Permanent" ng-checked="checkedPermanent" />&nbsp;永久有效
                </td>
            </tr>

        </table>
    </div>
</div>
</div>



AngularJS - Directive

l   directive-enabled-on.js

angular.module('enabledonapp', [])
.directive('enabledon', function () {
    return {
        scope: true,
        link: function ($scope) {

        },
        controller: function ($scope, $element) {
            //Initialize
            var date = new Date();
            $scope.EnabledOn = moment(date).format('YYYY/MM/DD');
        }
    }
});

l   directive-disable-on.js

angular.module('disabledonapp', [])
.directive('disabledon', function () {
    return {
        scope: true,
        link: function ($scope) {
           
            //當勾選/取消 永久有效 (Checkbox)
            $scope.$watch("Permanent", function (newValue, oldValue) {

                if (newValue == true) {
                    $scope.DisabledOn = '9999/12/31'
                    $scope.disabledDisabledOn = true;
                }
                else {
                    var date = new Date();
                    $scope.DisabledOn = moment(date).format('YYYY/MM/DD');
                    $scope.disabledDisabledOn = false;
                }
            });
        },
        controller: function($scope, $element) {
            //The watch can put here, it will execute before link function.

            $scope.checkedPermanent = false; //ng-check for Checkbox : 永久有效
            $scope.disabledDisabledOn = false; //ng-disable for Textbox : 停用日期

            //Initialize
            var date = new Date();
            $scope.DisabledOn = moment(date).format('YYYY/MM/DD');
        }
    }
});

Important!!
While creating directive, the parameters are defined as following.

scope
u  “false” : Use the parent scope.
u  “true” : Use the child scope inherit from the parent and which aren’t relevant to other directives.
u  “{}” : Isolated scope.
link
A function that contains the core logic of the directive.
controller
Controller for the directive.

For the difference between link and controller, you can take a look at this article on Stackflow.


AngularJS - Controller

var app =
angular.module('app', ['disabledonapp', 'enabledonapp'])
.controller('CreateCtrl', function ($scope, $http, $q) {

});



Implement : Create reusable HTML


Since we have the directive, it’s time to make the HTML reusable.
Fortunately, we can reach goal by Directive as well.

In the following sample, I will create only one directive for the input block which contain 2 textboxes and a checkbox.


HTML

l   Main Html

<div ng-app="app" ng-controller="EnabledDurationCtrl">
        <b>This is a test page for EnabledDuration directive</b>
        <hr />
        <div enabledduration>
        </div>
    </div>


l   EnabledDurationPartialView.html : reusable HTML (input block inside)

<div class="form-group">
    <label class="control-label col-md-2" for="EnabledOn">啟用日期</label>
    <div class="col-md-10">
        <input type="datetime" ng-model="EnabledOn"/>
    </div>
</div>

<div class="form-group">
    <label class="control-label col-md-2">停用日期</label>
    <div  class="col-md-10">
        <table width="100%">
            <tr>
                <td>
                    <input type="datetime" ng-disabled="disabledDisabledOn" ng-model="DisabledOn" />
                </td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox" ng-model="Permanent" ng-checked="checkedPermanent" />&nbsp;永久有效
                </td>
            </tr>

        </table>
    </div>
</div>


AngularJS : Directive

angular.module('enableddurationapp', [])
.directive('enabledduration', function () {
    return {
        scope: true,
        templateUrl: '/HTML/EnabledDurationPartialView.html',
        link: function ($scope) {
           
            //當勾選/取消 永久有效 (Checkbox)
            $scope.$watch("Permanent", function (newValue, oldValue) {

                if (newValue == true) {
                    $scope.DisabledOn = '9999/12/31'
                    $scope.disabledDisabledOn = true;
                }
                else {
                    var date = new Date();
                    $scope.DisabledOn = moment(date).format('YYYY/MM/DD');
                    $scope.disabledDisabledOn = false;
                }
            });
        },
        controller: function($scope, $element) {
            //The watch can put here, it will execute before link function.

            $scope.checkedPermanent = false; //ng-check for Checkbox : 永久有效
            $scope.disabledDisabledOn = false; //ng-disable for Textbox : 停用日期

            //Initialize
            var date = new Date();
            $scope.EnabledOn = moment(date).format('YYYY/MM/DD');
            $scope.DisabledOn = moment(date).format('YYYY/MM/DD');
        }
    }
});

Here we use templateUrl to include the reusable HTML in the directive.

The following picture shows the result.





Reference