【一起學(xué)AngularJS】專題篇——Providers

Providers

每個(gè)我們搭建的網(wǎng)站應(yīng)用都是由多個(gè)對(duì)象組成的送挑,它們互相之間交互來(lái)完成所有的工作训桶。要使得網(wǎng)站順利運(yùn)行午笛,這些對(duì)象需要首先被初始化并且聯(lián)系在一起渣刷。在AngularJS中鱼辙,大部分這樣的對(duì)象都是自動(dòng)的被Injector Service(注入器服務(wù))來(lái)初始化和編織在一起的廉嚼。
Injector服務(wù)創(chuàng)建兩種類型的對(duì)象:Services(服務(wù))和特殊對(duì)象
Service的API是由開(kāi)發(fā)者自己定義的倒戏。
特殊對(duì)象則對(duì)應(yīng)了AngularJS框架自帶的一些API怠噪。這些對(duì)象的類型有:Controller(控制器)Directive(指令)杜跷,Filter(過(guò)濾器)Animation(動(dòng)畫)傍念。
注入器需要知道按照什么方式來(lái)創(chuàng)建這些對(duì)象。我們可以通過(guò)注冊(cè)一個(gè)recipe(配方)定制創(chuàng)建對(duì)象的方式葛闷。一共有5種配方憋槐。
最冗長(zhǎng),但是最全面的一個(gè)是Provider配方淑趾。剩下的四種是:Value阳仔、Factory、Service和Constant扣泊,這些配方的功能和Provider一樣近范,僅僅是一些語(yǔ)法糖。
下面延蟹,我們來(lái)看一些不同的場(chǎng)景评矩,學(xué)習(xí)下如何通過(guò)不通的配方類型來(lái)創(chuàng)建和使用服務(wù)。


說(shuō)些關(guān)于模塊(Modules)的事

為了讓Injector知道如何創(chuàng)建對(duì)象并且編織它們阱飘,我們需要注冊(cè)對(duì)應(yīng)的配方斥杜。每個(gè)配方含有一個(gè)對(duì)象的標(biāo)識(shí)以及創(chuàng)建它的方式描述。
每個(gè)配方肯定是屬于某個(gè)Angular模塊的沥匈。一個(gè)Angular模塊就像一個(gè)包一樣蔗喂,包含了一個(gè)或者多個(gè)配方。由于手動(dòng)加載模塊依賴的其他對(duì)象是很麻煩的咐熙,所以模塊中也可以包含了需要依賴的其他模塊的信息弱恒。
當(dāng)一個(gè)Angular應(yīng)用以某個(gè)給定的模塊啟動(dòng)時(shí),Angular將先創(chuàng)建一個(gè)Injector的實(shí)例棋恼,然后這個(gè)實(shí)例再把定義在ng模塊的所有的配方返弹、應(yīng)用模塊 锈玉、依賴等作為一個(gè)總體統(tǒng)一注冊(cè)。


值配方Value Recipe

我們先來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的clientId服務(wù)义起,它將提供一個(gè)字符串拉背,是一個(gè)遠(yuǎn)程API的通信認(rèn)證碼。你可以下面這樣定義:

var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');

這里我們創(chuàng)建了一個(gè)叫做myApp的Angular模塊默终,并且定制了一張配方來(lái)創(chuàng)建clientId服務(wù)椅棺,這里的配方就是'a12345654321x'這個(gè)字符串,這個(gè)例子很簡(jiǎn)單不是么齐蔽?
下面你就可以通過(guò)數(shù)據(jù)綁定來(lái)顯示它了:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
  this.clientId = clientId;
}]);
<html ng-app="myApp">
  <body ng-controller="DemoController as demo">
    Client ID: {{demo.clientId}}
  </body>
</html>

在這個(gè)例子中两疚,我們使用了值配方來(lái)定義了一個(gè)服務(wù)的返回值。當(dāng)DemoController調(diào)用這個(gè)clientId服務(wù)的時(shí)候含滴,將返回這個(gè)值诱渤。
相信你可以舉一反三!

工廠配方Factory Recipe

值配方寫起來(lái)非常簡(jiǎn)便谈况,但同時(shí)也缺少了一些我們創(chuàng)建服務(wù)時(shí)需要的重要特性勺美。下面我們來(lái)看看值配方的兄弟——工廠配方。工廠配方比值配方多了以下功能:

  • 使用其他服務(wù)(能依賴其他服務(wù))
  • 服務(wù)初始化
  • 延遲加載
    這個(gè)工廠配方將通過(guò)一個(gè)可帶參數(shù)(對(duì)其他服務(wù)的依賴)的函數(shù)來(lái)創(chuàng)建一個(gè)服務(wù)碑韵。函數(shù)的返回值就是按照此配方創(chuàng)建的服務(wù)實(shí)例赡茸。

注意:Angular中所有的服務(wù)都是單例的。這意味著注入器將且僅將使用一次創(chuàng)建某個(gè)對(duì)象的配方祝闻。然后注入器就會(huì)緩存所有的實(shí)例引用占卧,以便將來(lái)的使用。

工廠配方是值配方的一個(gè)更高級(jí)的形式治筒,所以上面的例子使用工廠配方同樣可以創(chuàng)建屉栓。如下:

myApp.factory('clientId', function clientIdFactory() {
  return 'a12345654321x';
});

但是這里的token是簡(jiǎn)單的字符串,使用值配方似乎更加簡(jiǎn)單耸袜,并且代碼也更加簡(jiǎn)潔友多。
我們來(lái)做點(diǎn)復(fù)雜的操作,下面我們來(lái)創(chuàng)建一個(gè)能計(jì)算token用于校驗(yàn)遠(yuǎn)程API的服務(wù)堤框。這個(gè)token的叫做apiToken域滥,它將由存儲(chǔ)在瀏覽器本地內(nèi)存的一個(gè)密鑰和客戶端編號(hào)clientId計(jì)算而來(lái)。

myApp.factory('apiToken', ['clientId', function apiTokenFactory(clientId) {
  var encrypt = function(data1, data2) {
    // NSA-proof encryption algorithm:
    return (data1 + ':' + data2).toUpperCase();
  };

  var secret = window.localStorage.getItem('myApp.secret');
  var apiToken = encrypt(clientId, secret);

  return apiToken;
}]);

在上述代碼中蜈抓,apiToken服務(wù)是通過(guò)工廠配方創(chuàng)建的启绰,而這個(gè)工廠配方依賴了clientId服務(wù)。這個(gè)工廠配方中使用了NSA-proof加密算法來(lái)產(chǎn)生一個(gè)驗(yàn)證token沟使。

最佳實(shí)踐: 工廠函數(shù)我們一般命名成 <serviceId>Factory(比如: apiTokenFactory). 當(dāng)然命名公約不是必須的委可,它在查找代碼和查看堆棧時(shí)很有用。

就像值配方一樣,工廠配方可以創(chuàng)建一個(gè)任何類型的服務(wù)着倾,可以是基本類型拾酝,也可以是函數(shù),或者自定義類型的實(shí)例卡者。

服務(wù)配方 Service Recipe

JavaScript開(kāi)發(fā)者經(jīng)常使用自定義類型去編寫面像對(duì)象的代碼蒿囤。下面是一個(gè)自定義實(shí)例——unicornLauncher服務(wù),它將把我們的獨(dú)角獸發(fā)射到空中【注解:我也沒(méi)看懂為啥舉這個(gè)例子崇决,獨(dú)角獸有其他含義材诽?】

function UnicornLauncher(apiToken) {

  this.launchedCount = 0;
  this.launch = function() {
    // Make a request to the remote API and include the apiToken
    ...
    this.launchedCount++;
  }
}

現(xiàn)在我們已經(jīng)準(zhǔn)備好發(fā)射獨(dú)角獸了,不過(guò)apiToken服務(wù)還沒(méi)有依賴進(jìn)來(lái)恒傻,我們通過(guò)工廠配方來(lái)將其引用進(jìn)來(lái):

myApp.factory('unicornLauncher', ["apiToken", function(apiToken) {
  return new UnicornLauncher(apiToken);
}]);

然而這個(gè)例子最佳的解決方案是使用服務(wù)配方脸侥。
服務(wù)配方也能像工廠配方和值配方一樣創(chuàng)建一個(gè)服務(wù),但它是通過(guò)使用new操作符來(lái)調(diào)用一個(gè)構(gòu)造器來(lái)實(shí)現(xiàn)的碌冶。這個(gè)構(gòu)造器可以接受0個(gè)或者多個(gè)參數(shù)湿痢,用于傳入這個(gè)服務(wù)實(shí)例所依賴的服務(wù)涝缝。

注意:服務(wù)配方的設(shè)計(jì)方式遵循構(gòu)造器注入

上文中我們已經(jīng)為UnicornLauncher設(shè)計(jì)了一個(gè)構(gòu)造器扑庞,所以我們只需要通過(guò)下面的代碼就可以把上文中的工廠配方編程服務(wù)配方了:

myApp.service('unicornLauncher', ["apiToken", UnicornLauncher]);

是不是更加簡(jiǎn)單了!>艽罐氨!

注意: 我們把配方的一種叫做了“服務(wù)”。我們很后悔這么做滩援,而且我們知道我們?cè)缤頃?huì)被懲罰的栅隐。這就像我們把我們的子孫叫做“孩子”一樣,這樣他的老師就會(huì)很郁悶了(注解:老師喊他的名字的時(shí)候玩徊,其他小孩就會(huì)納悶)租悄。

提供者配方Provider Recipe
之前我們提到過(guò),提供者配方是核心配方恩袱,其他配方只是在其基礎(chǔ)之上構(gòu)建的語(yǔ)法糖而已泣棋。提供者配方非常冗長(zhǎng)繁瑣,但是其功能也最強(qiáng)大畔塔,只是對(duì)于大多數(shù)情況來(lái)說(shuō)潭辈,使用它有點(diǎn)過(guò)了。
提供者配方語(yǔ)法上是一個(gè)實(shí)現(xiàn)了$get方法的自定義類型澈吨。這個(gè)方法其實(shí)是一個(gè)工廠方法把敢,和我們之前討論的工廠配方?jīng)]什么不通。實(shí)際上谅辣,當(dāng)你創(chuàng)建了一個(gè)工廠配方時(shí)修赞,本質(zhì)是創(chuàng)建了一個(gè)提供者配方,只是其中的$get方法指向了你的工廠方法而已桑阶,當(dāng)然這一切對(duì)用戶來(lái)說(shuō)都是透明的柏副。
使用提供者配方只有一個(gè)場(chǎng)景熙尉,那就是當(dāng)你需要暴露一些可以在應(yīng)用啟動(dòng)之前配置應(yīng)用的API的時(shí)候。這在各個(gè)AngularJS應(yīng)用重用服務(wù)的時(shí)候特別有用搓扯。
我們的unicornLauncher服務(wù)太了检痰,所以很多應(yīng)用(AngularJS應(yīng)用)都在用它。默認(rèn)的情況下锨推,獨(dú)角獸號(hào)沒(méi)有護(hù)盾铅歼。但是在很多星球上,大氣層非常的厚换可,以至于我們必須要給獨(dú)角獸號(hào)裝上錫紙護(hù)盾椎椰,這樣它就可以翱翔在銀河系中惹,而不是燒毀在大氣層中U傣(PS:老外的教程就是這么體貼慨飘,連舉例都像那么回事!一點(diǎn)不馬虎)译荞。要是能夠在每個(gè)發(fā)射應(yīng)用中配置發(fā)射時(shí)是否安裝錫紙護(hù)盾就好了瓤的,應(yīng)用就可以根據(jù)自己的大氣層情況決定是否安裝了。 答案當(dāng)然是可以的吞歼。我們可以讓它變成可配置的:

myApp.provider('unicornLauncher', function UnicornLauncherProvider() {
  var useTinfoilShielding = false;

  this.useTinfoilShielding = function(value) {
    useTinfoilShielding = !!value;
  };

  this.$get = ["apiToken", function unicornLauncherFactory(apiToken) {

    // let's assume that the UnicornLauncher constructor was also changed to
    // accept and use the useTinfoilShielding argument
    return new UnicornLauncher(apiToken, useTinfoilShielding);
  }];
});

為了開(kāi)啟錫紙護(hù)盾圈膏,我們需要?jiǎng)?chuàng)建一個(gè)配置模塊,并且把UnicornLauncherProvider注入進(jìn)去篙骡。

myApp.config(["unicornLauncherProvider", function(unicornLauncherProvider) {
  unicornLauncherProvider.useTinfoilShielding(true);
}]);

注意獨(dú)角獸號(hào)提供者已經(jīng)被注入了配置函數(shù)稽坤。這次注入是由提供者注入器來(lái)注入的,它不同于普通的實(shí)例注入器糯俗。提供者注入器只注入和綁定所有的提供者實(shí)例尿褪。
在應(yīng)用啟動(dòng)階段,在Angular創(chuàng)建所有服務(wù)之前得湘,它配置并且初始化所有的提供者杖玲。我們把這個(gè)階段叫做配置階段,它是Angular應(yīng)用生命周期的一部分忽刽。在這個(gè)階段中天揖,服務(wù)是無(wú)法被訪問(wèn)的,因?yàn)樗鼈冞€沒(méi)有被初始化跪帝。
一旦配置階段結(jié)束后今膊,與提供者的交互舊結(jié)束了,配置和初始化服務(wù)的階段開(kāi)始了伞剑,我們把后面的這個(gè)階段叫做運(yùn)行階段斑唬。

常量配方 Constant Recipe

我們剛剛知道了Angular把生命周期分為配置階段和運(yùn)行階段,并且你應(yīng)該也知道了你可以通過(guò)配置函數(shù)來(lái)配置你的應(yīng)用。因?yàn)榕渲秒A段中恕刘,所有服務(wù)實(shí)例都是無(wú)法被訪問(wèn)的缤谎,簡(jiǎn)單的值配方實(shí)例(Value Objects)也是如此。
但是確實(shí)有些時(shí)候我們需要在配置階段訪問(wèn)一些變量褐着,而不是采用硬編碼坷澡。而且大多數(shù)時(shí)候我們需要在配置和運(yùn)行階段都能訪問(wèn)到這些變量。這就輪到常量配方( Constant Recipe)來(lái)大顯身手了含蓉。
下面我們要在配置階段在準(zhǔn)備發(fā)射時(shí)為我們的獨(dú)角獸號(hào)打上星球名稱的標(biāo)簽频敛。星球名稱是應(yīng)用指定的,并且在運(yùn)行時(shí)期能被各種各樣的控制器使用馅扣。為了達(dá)到這個(gè)效果斟赚,我們可以創(chuàng)建一個(gè)常量:

myApp.constant('planetName', 'Greasy Giant');

然后,我們就可以像下面這樣來(lái)配置unicornLauncherProvider了:

myApp.config(['unicornLauncherProvider', 'planetName', function(unicornLauncherProvider, planetName) {
  unicornLauncherProvider.useTinfoilShielding(true);
  unicornLauncherProvider.stampText(planetName);
}]);

因?yàn)槌A颗浞皆谶\(yùn)行階段也能被訪問(wèn)差油,所以我們也可以在控制器和模版中使用它:

myApp.controller('DemoController', ["clientId", "planetName", function DemoController(clientId, planetName) {
  this.clientId = clientId;
  this.planetName = planetName;
}]);
<html ng-app="myApp">
  <body ng-controller="DemoController as demo">
   Client ID: {{demo.clientId}}
   <br>
   Planet Name: {{demo.planetName}}
  </body>
</html>

特殊目的對(duì)象 Special Purpose Objects

之前我們談到過(guò)有一些不同于服務(wù)的特殊目的對(duì)象拗军。這些對(duì)象是Angular框架的插件式擴(kuò)展,因此它們都實(shí)現(xiàn)了Angular指定的接口蓄喇。這些接口包含:控制器发侵、指令(Directive)、過(guò)濾器和動(dòng)畫公罕。
注入器創(chuàng)建特殊對(duì)象時(shí)(以及控制器對(duì)象的異常)所使用的指令是通過(guò)工廠配方實(shí)現(xiàn)的器紧,當(dāng)然這個(gè)實(shí)現(xiàn)過(guò)程對(duì)用戶來(lái)說(shuō)是透明的。
下面我們舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明如果通過(guò)指令A(yù)PI(它依賴于我們之前的那個(gè)常量配方plantName楼眷,在本例中它叫"Plant Name:Greasy Giant")創(chuàng)建一個(gè)簡(jiǎn)單的控件。
由于指令的注冊(cè)是通過(guò)工廠配方來(lái)完成的熊尉,因此我們可以使用和工廠配方相同的語(yǔ)法:

myApp.directive('myPlanet', ['planetName', function myPlanetDirectiveFactory(planetName) {
  // directive definition object
  return {
    restrict: 'E',
    scope: {},
    link: function($scope, $element) { $element.text('Planet: ' + planetName); }
  }
}]);

然后我們就可以像下面一樣使用這個(gè)控件了:

<html ng-app="myApp">
  <body>
   <my-planet></my-planet>
  </body>
</html>

通過(guò)這種工廠配方的方式罐柳,我們可以定義AnuglarJS的過(guò)濾器和注解,但是定義控制器則有點(diǎn)特別狰住。我們定義一個(gè)控制器為自定義類型张吉,并且通過(guò)構(gòu)造函數(shù)的參數(shù)申明它的依賴服務(wù),然后控制器將作為模塊的一部分被注冊(cè)催植。我們來(lái)看看之前我們的一個(gè)例子DemoController

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
  this.clientId = clientId;
}]);

每次應(yīng)用需要一個(gè)DemoController實(shí)例的時(shí)候(在我們的例子應(yīng)用中肮蛹,只有一次),DemoController都將通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)新的實(shí)例创南。因此控制器和服務(wù)不一樣伦忠,因?yàn)樗鼈儾皇菃卫摹C慨?dāng)控制器的構(gòu)造函數(shù)被調(diào)用時(shí)稿辙,都會(huì)調(diào)用所依賴的服務(wù)(本例子中是clientId服務(wù))昆码。

結(jié)論

讓我們總結(jié)幾點(diǎn)重要的:

  • 注入器使用配方來(lái)創(chuàng)建兩類對(duì)象:服務(wù) 和 特殊對(duì)象
  • 一共有5種配方:工廠配方、值配方、服務(wù)配方赋咽、提供者配方旧噪、常量配方附帽。
  • 工廠配方和服務(wù)配方是最常用的配方啊奄。它們兩者的區(qū)別在于:服務(wù)配方適用于創(chuàng)建自定義類型的實(shí)例蟀苛,而工廠配方可以更好的創(chuàng)建JavaScript基本類型和函數(shù)的實(shí)例怠肋。
  • 提供者配方是核心配方蛮寂,并且其他的配方都是基于提供者配方的語(yǔ)法糖莉钙。
  • 提供者是最復(fù)雜的配方類型纯路,除非你需要為一些重用的代碼做全局多態(tài)化配置宛瞄,否則盡量少用缤骨。(注解:舉個(gè)例子爱咬,你是老板,有3個(gè)司機(jī)(多應(yīng)用)和一輛寶馬(公用代碼)绊起,你希望每次喊他們服務(wù)來(lái)服務(wù)的時(shí)候精拟,都能開(kāi)你的寶馬,但是3個(gè)司機(jī)各有的坐墊癖好虱歪,有人喜歡皮的蜂绎,有人喜歡布的,有人則不喜歡坐墊笋鄙。這就是對(duì)同一輛寶馬的多太)
  • 所有的特殊對(duì)象除了控制器师枣,都是通過(guò)工廠配方定義的。
Features Recipe type Factory Service Value Constant Provider
can have dependencies yes yes no no yes
uses type friendly injection no yes yes* yes* no
object available in config phase no no no yes yes**
can create functions yes yes yes yes yes
can create primitives yes no yes yes yes

* 需要使用new操作符來(lái)完成初始化
** 在配置階段是無(wú)法訪問(wèn)服務(wù)對(duì)象的萧落,但是可以訪問(wèn)提供者對(duì)象践美。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市找岖,隨后出現(xiàn)的幾起案子陨倡,更是在濱河造成了極大的恐慌,老刑警劉巖许布,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兴革,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蜜唾,警方通過(guò)查閱死者的電腦和手機(jī)杂曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)袁余,“玉大人擎勘,你說(shuō)我怎么就攤上這事∶诨簦” “怎么了货抄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵述召,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蟹地,道長(zhǎng)积暖,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任怪与,我火速辦了婚禮夺刑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘分别。我一直安慰自己遍愿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布耘斩。 她就那樣靜靜地躺著沼填,像睡著了一般。 火紅的嫁衣襯著肌膚如雪括授。 梳的紋絲不亂的頭發(fā)上坞笙,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音荚虚,去河邊找鬼薛夜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛版述,可吹牛的內(nèi)容都是我干的梯澜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼渴析,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼晚伙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起檬某,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撬腾,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后恢恼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胰默,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年场斑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牵署。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漏隐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奴迅,到底是詐尸還是另有隱情青责,我是刑警寧澤挺据,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站脖隶,受9級(jí)特大地震影響扁耐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜产阱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一婉称、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧构蹬,春花似錦王暗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至藻烤,卻和暖如春绷雏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隐绵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工之众, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人依许。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓棺禾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親峭跳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膘婶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容