基本概念和用法-MVC 2-2

如何復用Model?

數據模型也就是Model,在AngularJS里面是怎么實現的

<!DOCTYPE html>
<html lang="en" ng-app>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <input type="text" ng-model="greeting.text"/>
        <p>{{greeting.text}},Angular</p>
    </div>
</body>
<script src="js/angular-1.3.0.js"></script>
</html>

這段代碼寫了一個input輸入框,這個里面通過ng-model這樣一個指令生成一個數據模型,這個數據模型他的結構是greeting.text,在下面的p標簽里面通過花括號來取值,獲得greeting.text這個模型的值,
這個是Angular JS里面實現數據模型的一種方式,運行的效果是input進行輸入的時候p標簽會實時的去更新,p標簽里面的內容實際上是綁定了ng-model相同的內容上面,這個例子里面實際上是沒有寫任何一段js代碼的。

Angular JS 首先會在Angular JS加載完成之后他會啟動,啟動完了以后首先去找ng-app這個指令,找到這個指令他就認為ng-app這個標簽內部所有的內容都歸Angular JS去管,這個時候她就回去找子層表情所有的指令,對他進行編譯操作,這個時候他就會找到ng-model,找到ng-model后會幫我們生成一個數據模型,這個數據模型是掛在所謂的$rootscope上面,也就是根作用域上面的,所以ng-app下面的所有子層標簽任意一個層級上都可以去獲取{{greeting.text}}這樣一個值。

Angular JS里面的數據模型一般來說是不需要你自己手動去創建的,也就是說你不需要明確的去new一個model這樣一個東西,Angular JS里面的數據模型他一般都是綁定在$scope這樣一個對象上面的,

<!doctype html>
<html ng-app="HelloAngular">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <div ng-controller="Commoncontroller">
            <!-- ng-controller控制器 -->
            <div ng-controller="Controller1">
                <p>{{greeting.test}},Angular</p>
                <button ng-click="test1()">test1</button>
                <button ng-click="commonFn()">通用</button>
            </div>
            <div ng-controller="Controller2">
                <p>{{greeting.test}},Angular</p>
                <button ng-click="test2()">test2</button>
                <button ng-click="commonFn()">通用</button>
            </div>
            <button ng-click="commonFn()">通用</button>
        </div>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="HelloAngular_MVC3lx.js"></script>
</html>

var myModule = angular.module("HelloAngular", []);

myModule.controller("Commoncontroller", ['$scope',
    function($scope){
        $scope.commonFn = function(){
            alert("這里是通用功能")
        }
    }
]);

myModule.controller("Controller1", ['$scope',
    function($scope) {
        $scope.greeting = {
            test:'hello1'
        }
        $scope.test1=function(){
            alert("test1")
        }
    }
]);

myModule.controller("Controller2", ['$scope',
    function($scope) {
        $scope.greeting = {
            test:'hello2'
        }
        $scope.test2=function(){
            alert("test2")
        }
    }
]);
Paste_Image.png

上面的例子中可以看到我們獲得最終的hello1和hello2在界面上顯示實際上都是來自于$scope這里面對象的屬性這就是AngularJS實現數據模型的方式,

如何復用Viel視圖?

html

<!doctype html>
<html ng-app="MyModule">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <hello></hello>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="HelloAngular_Directive.js"></script>
</html>

javascript

var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
    return {
        restrict: 'E',
        template: '<div>Hi everyone!</div>',
        replace: true
    }
});

運行效果

Paste_Image.png

看看body表情內的<hello></hello>標簽,很顯然瀏覽器是不認識這個標簽的,不認識他在默認情況下瀏覽器會忽略他,Angular js就會想一下怎樣能讓瀏覽器認識這個標簽呢,這就需要借助Angular js的Directive這個特性,

上面代碼,自己定義了一個hello標簽,然后借助Angular的directive機制把他替換成div內容是Hi everyone!這樣一個字符串,

Angular js的視圖是需要通過指令去實現的,

Angular js的MVC是借助于$scope實現的!!!

也就是說全部借助于作用域去實現的

那么作用域是什么呢

.show-scope-demo .ng-scope,.show-scope-demo .ng-scope {
    border: 1px solid red;
    margin: 3px;
}
<!doctype html>
<html ng-app>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="Scope1.css" />
    </head>
    <body>
        <div class="show-scope-demo">
            <div ng-controller="GreetCtrl">
                Hello {{name}}!
            </div>
            <div ng-controller="ListCtrl">
                <ol>
                    <li ng-repeat="name in names">
                        {{name}} from {{department}}
                    </li>
                </ol>
            </div>
        </div>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="Scope1.js"></script>
</html>


function GreetCtrl($scope, $rootScope) {
    $scope.name = 'World';
    $rootScope.department = 'Angular';
}

function ListCtrl($scope) {
    $scope.names = ['Igor', 'Misko', 'Vojta'];
}

Paste_Image.png

以上代碼有兩個控制器,第一個GreetCtrl,第二個ListCtrl,

GreetCtrl里面Hello {{name}}!

ListCtrl里面使用到了ng-repeat的指令,這個指令是用來迭代一個數組的,我們有一個names數組放了很多的姓名,

使用ng-repeat的指令可以將數組一個個輸出,

function GreetCtrl($scope, $rootScope) {
    $scope.name = 'World';
    $rootScope.department = 'Angular';
}

function ListCtrl($scope) {
    $scope.names = ['Igor', 'Misko', 'Vojta'];
}

GreetCtrl控制器中$scope.name設置了 'World';的字符串

然后在$rootScope上面創建了一個屬性叫做department

$rootScope也就是根作用域,$rootScope是處于最頂層的作用域對象,

整個作用域就像html標簽一樣是一個樹型的結構,$rootScope就類似于根標簽html。

ListCtrl控制器中有一個names數組,數組有三個內容,在頁面上通過ng-repeat的指令把他輸出

頁面顯示結果告訴我們department 是根作用于上的屬性,也就是說作用域是有一個層次結構的,在內層的作用域上面如果獲得不到的屬性他就會一一向上查找,這個過程其實和js里面的原型繼承或者說原型查找機制是一模一樣的。

例子

<!doctype html>
<html ng-app>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="Scope1.css" />
    </head>
    <body>
        <div ng-controller="EventController">
            Root scope
            <tt>MyEvent</tt> count: {{count}}
            <ul>
                <li ng-repeat="i in [1]" ng-controller="EventController">
                    <button ng-click="$emit('MyEvent')">
                        $emit('MyEvent')
                    </button>
                    <button ng-click="$broadcast('MyEvent')">
                        $broadcast('MyEvent')
                    </button>
                    <br>
                    Middle scope
                    <tt>MyEvent</tt> count: {{count}}
                    <ul>
                        <li ng-repeat="item in [1, 2]" ng-controller="EventController">
                            Leaf scope
                            <tt>MyEvent</tt> count: {{count}}
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </body>
    <script src="js/angular-1.3.0.js"></script>
    <script src="Scope2.js"></script>
</html>
function EventController($scope) {
    $scope.count = 0;
    $scope.$on('MyEvent', function() {
        $scope.count++;
    });
}

Paste_Image.png
Paste_Image.png

ng-repeat="i in [1]"是內聯表達式。

function EventController($scope) {
    $scope.count = 0;
    $scope.$on('MyEvent', function() {
        $scope.count++;
    });
}

這里的js,先初始化一個$scope.count = 0;

當收到MyEvent的時候$scope上的count就會加1

神奇的$scope

$scope是一個POJO(Plain Old Javascript Object)

$scope是一個普通的js對象

$scope提供了一些工具方法$watch()/$apply()

$watch()/$apply()是用來實時監控一些屬性的變化的一般來說不會手動去調用這些方法。他會在內部幫我們去監控

$scope是表達式的執行環境(或者叫作用域)

$scope是一個樹型結構,與DOM標簽平行

子$scope對象會繼承父$scope上的屬性和方法

每一個AngularJS應用只有一個根$scope對象,(一般位于ng-app上)

$scope可以傳播事件,類似于DOM事件,可以向上也可以向下

$scope不僅是MVC的基礎,也是后面實現雙向數據綁定的基礎

可以用angular.element($0).scope()進行調試

Paste_Image.png

安裝調試插件

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容