Oleh kerana keperluan pembangunan sebenar di tempat kerja, saya mula bersentuhan dengan rangka kerja sudut. Dari perbandingan awal, terseksa dan hancur dengan pelbagai masalah dan konsep, kini saya mempunyai kefahaman tertentu dan merasakan keperluan untuk merumuskan secara ringkas pemahaman saya. Mohon maaf atas segala kekurangan.
1. Pengikatan data dua hala
Pelbagai rangka kerja MV** kini popular dalam industri, dan rangka kerja berkaitan sentiasa muncul, dan sudut adalah salah satu daripadanya (MVVM). Malah, isu teras rangka kerja MV** adalah untuk memisahkan lapisan paparan daripada model, mengurangkan gandingan kod dan mencapai pemisahan data dan prestasi MVC, MVP dan MVVM semuanya mempunyai matlamat yang sama. tetapi perbezaan antara mereka Ia terletak pada cara mengaitkan lapisan model dengan pandangan.
Cara data mengalir dalam model dan lapisan paparan telah menjadi kunci kepada masalah Angular melaksanakan pengikatan dua hala data melalui pemeriksaan kotor. Apa yang dipanggil pengikatan dua hala bermakna perubahan dalam paparan boleh dicerminkan dalam lapisan model, dan perubahan dalam data model boleh dicerminkan dalam paparan. Jadi bagaimanakah Angular mencapai pengikatan dua hala Mengapa ia menjadi semakan kotor? Mari mulakan dengan soalan asal di bahagian hadapan:
html:
<input type="button" value="increase 1" id="J-increase" /> <span id="J-count"></span>
js:
<script> var bindDate = { count: 1, appy: function () { document.querySelector('#J-count').innerHTML = this.count; }, increase: function () { var _this = this; document.querySelector('#J-increase').addEventListener('click', function () { _this.count++; appy(); }, true); }, initialize: function () { // 初始化 this.appy(); // this.increase(); } }; bindDate.initialize(); </script>
Dalam contoh di atas, terdapat dua proses:
Lapisan paparan mempengaruhi lapisan model: Mengklik butang pada halaman menyebabkan bilangan kiraan data meningkat sebanyak 1
Lapisan model mencerminkan lapisan paparan: Selepas kiraan berubah, ia dicerminkan pada lapisan paparan melalui fungsi guna
Ini adalah pemprosesan data yang sebelum ini dilaksanakan menggunakan perpustakaan seperti jquery dan YUI Masalah di sini adalah jelas:
// 对angular里面的源码进行了精简 $watch: function(watchExp, listener, objectEquality) { var scope = this, array = scope.$$watchers, watcher = { fn: listener, last: initWatchVal, get: get, exp: watchExp, eq: !!objectEquality }; if (!array) { array = scope.$$watchers = []; } array.unshift(watcher); }
$digest: function() { while (length--) { watch = watchers[length]; watch.fn(value, lastValue, scope); } }
2. Suntikan kebergantungan
Pelajar yang telah menggunakan rangka kerja spring tahu bahawa Ioc dan AOP ialah dua konsep yang paling penting dalam musim bunga, dan Ioc boleh digunakan untuk menyuntik kebergantungan (DI) Jelas sekali bahawa sudut mempunyai warna hujung belakang yang sangat kuat.
Begitu juga, mari kita lihat dahulu cara menyelesaikan kesalingbergantungan objek tanpa menggunakan DI:
function Car() { ... } Car.prototype = { run: function () {...} } function Benz() { var cat = new Car(); } Benz.prototype = { ... }
1. Anotasi simulasi
// 注解的模拟 function annotate(fn, strictDi, name) { var $inject; if (!($inject = fn.$inject)) { $inject = []; $inject.push(name); }else if (isArray(fn)) { $inject = fn.slice(0, last); } return $inject; } createInjector.$$annotate = annotate;
function createInjector(modulesToLoad, strictDi) { //通过singleton模式创建对象 var providerCache = { $provide: { provider: supportObject(provider), factory: supportObject(factory), service: supportObject(service), value: supportObject(value), constant: supportObject(constant), decorator: decorator } }, instanceCache = {}, instanceInjector = (instanceCache.$injector = createInternalInjector(instanceCache, function(serviceName, caller) { var provider = providerInjector.get(serviceName + providerSuffix, caller); return instanceInjector.invoke(provider.$get, provider, undefined, serviceName); })); return instanceInjector; }
function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); for (...) { key = $inject[i]; // 替换成依赖的对象 args.push( locals && locals.hasOwnProperty(key) ? locals[key] : getService(key, serviceName) ); } if (isArray(fn)) { fn = fn[length]; } return fn.apply(self, args); }
3.komunikasi pengawal
Dalam pembangunan sebenar, sistem aplikasi akan menjadi sangat besar. Adalah mustahil untuk aplikasi aplikasi hanya mempunyai satu pengawal, jadi terdapat kemungkinan komunikasi antara pengawal yang berbeza Terdapat dua cara utama untuk menyelesaikan masalah biasa ini:
Daftar acara di $rootScope Masalahnya ialah terlalu banyak acara akan didaftarkan pada $rootScope, yang akan menyebabkan beberapa masalah seterusnya.
//controller1 app.controller('controller1', function ($rootScope) { $rootScope.$on('eventType', function (arg) { ...... }) }) // controller2 app.controller('controller2', function ($rootScope) { $rootScope.$emit('eventType',arg); or $rootScope.$broadcast('eventType',arg); })
dan gunakan ciri bahawa perkhidmatan adalah satu tunggal untuk bertindak sebagai jambatan antara pengawal yang berbeza
4.Ciri perkhidmatan
1. Singleton: Hanya perkhidmatan dalam sudut boleh melakukan DI seperti pengawal dan arahan tidak mempunyai fungsi ini secara literal tidak berkaitan dengan perniagaan tertentu, manakala pengawal dan arahan berkait rapat dengan perniagaan tertentu, jadi keunikan perkhidmatan perlu dipastikan.
2. lazy new: angular akan mula-mula menjana penyedia perkhidmatan, tetapi tidak serta-merta menjana perkhidmatan yang sepadan Ia hanya akan membuat seketika perkhidmatan ini apabila ia diperlukan. .
3. Pembekal) klasifikasi: pembekal(), kilang, perkhidmatan, nilai, pemalar, di mana penyedia adalah pelaksanaan paling rendah, dan kaedah lain berdasarkannya Gula sintaksis ( gula), perlu diperhatikan bahawa perkhidmatan ini akhirnya akan menambah kaedah $get, kerana perkhidmatan khusus dihasilkan dengan melaksanakan kaedah $get.
5. Pelaksanaan arahan
Penyusunan arahan merangkumi dua peringkat: menyusun dan memaut. Secara ringkasnya, fasa penyusunan terutamanya berkaitan dengan templat DOM Pada masa ini, isu skop tidak terlibat, iaitu, tiada pemaparan data dilakukan Sebagai contoh, arahan ngRepeate mengubah templat melalui kompilasi , fungsi pautan akan dikembalikan, menimpa pautan yang ditakrifkan kemudiannya digunakan terutamanya untuk pemaparan data, yang dibahagikan kepada dua pautan: pra-pautan dan pasca pautan adalah terbalik. Pautan pasca menghuraikan bahagian dalaman dahulu, dan kemudian bahagian luaran Ini mempunyai kesan yang besar pada arahan adalah selamat kerana arahan juga boleh menyertakan arahan Pada masa yang sama, pautan memproses DOM sebenar, yang akan melibatkan isu prestasi dalam operasi DOM.
Kandungan yang diliputi dalam artikel ini tidak begitu universal, dan akan ada suplemen yang sepadan nanti. Saya harap semua orang juga boleh belajar dan membincangkan rangka kerja sudut.