odoo V10中文參考手冊(cè)(八:Javascript)

Javascript

Widgets

web.Widget輸出class Widget()诅诱,是所有可視組件的基類偶妖,相當(dāng)于mvc的view層昌执,提供一系列的處理頁(yè)面的方法

  • 處理多widget之間的繼承奈梳、被繼承關(guān)系
  • 提供可擴(kuò)展的生命周期安全管理(當(dāng)父類被destruct時(shí)自動(dòng)將對(duì)應(yīng)子類清除)
  • 自動(dòng)使用qweb引擎渲染
  • 與backbone兼容的快捷方法

DOM根元素

Widget()負(fù)責(zé)的是根DOM下的一部分widget頁(yè)面,可以通過(guò)兩個(gè)屬性來(lái)獲取widget的DOM:

  • Widget.el - widget對(duì)應(yīng)的原始根DOM
  • Widget.$el - 使用jQuery選擇的el

有兩種方法來(lái)定義生成DOM根元素:

  • Widget.template - qweb的模板名射富,指定模板會(huì)在widget初始化之后、實(shí)際渲染之前渲染盆色。該模板生成的根元素就會(huì)作為對(duì)應(yīng)widget的DOM根元素
  • Widget.tagName - 當(dāng)沒(méi)有設(shè)置模板名的時(shí)候使用灰蛙,默認(rèn)是div祟剔,它會(huì)被設(shè)置成widget的DOM根元素,可以通過(guò)以下屬性來(lái)自定義對(duì)應(yīng)DOM根元素:
  • Widget.id - 在DOM根元素上生成一個(gè)id屬性
  • Widget.className - 在DOM根元素上生成一個(gè)class屬性
  • Widget.attributes - 屬性映射表摩梧,會(huì)自動(dòng)將里面的鍵值對(duì)設(shè)置為根元素的對(duì)應(yīng)屬性
  • 當(dāng)設(shè)置了模板名物延,上述參數(shù)將不能使用
  • Widget.renderElement() - 可以通過(guò)此方法來(lái)渲染widget的根DOM并設(shè)置,使用的是template或tagName仅父,并調(diào)用setElement() 來(lái)設(shè)置
  • 可以覆蓋renderElement() 方法來(lái)實(shí)現(xiàn)自定義的渲染叛薯,但是如果沒(méi)有在里面調(diào)用__super的話必須要調(diào)用setElement() 方法

使用widget

widget的生命周期分三個(gè)階段:

  • 1.創(chuàng)建并初始化
    Widget.init(parent) - widget的初始化方法,可以接收更多的參數(shù)來(lái)覆蓋父級(jí)widget

參數(shù):
parent (Widget()) - 新創(chuàng)建的widget的父級(jí)笙纤,如果某widget沒(méi)有父級(jí)可傳null

  • 2.注入DOM并啟動(dòng)案训,通過(guò)調(diào)用以下方法中的一個(gè)來(lái)完成
  • Widget.appendTo(element) - 渲染widget并用jquery的appendTo添加到對(duì)應(yīng)DOM最后一個(gè)后元素前
  • Widget.prependTo(element) 渲染widget并用jquery的prependTo插入到對(duì)應(yīng)DOM第一個(gè)子元素前
  • Widget.insertAfter(element) - 渲染widget并用jquery的insertAfter添加到對(duì)應(yīng)dom之后
  • Widget.insertBefore(element) - 渲染widget并用jquery的insertBefore添加到對(duì)應(yīng)dom之前

上述方法接收的參數(shù)和對(duì)應(yīng)jquery方法接收的參數(shù)一致,會(huì)返回一個(gè) deferred延遲執(zhí)行對(duì)象粪糙,并賦予三個(gè)任務(wù):

1.使用renderElement()來(lái)渲染widget的根元素
2.用對(duì)應(yīng)的jquery方法將widget插入到dom中
3.啟動(dòng)widget并將啟動(dòng)的結(jié)果返回
Widget.start():當(dāng)widget被插入到DOM之后異步啟動(dòng)强霎,一般用于異步的rpc調(diào)用以獲取遠(yuǎn)端數(shù)據(jù)用于widget中,完成后需要返回一個(gè)deferred對(duì)象蓉冈。在start方法執(zhí)行完成之前widget的功能不一定是完整的城舞。

  • 3.銷毀并清除widget對(duì)象
    Widget.destroy() - 銷毀它的子類,解綁所有事件寞酿,將它的根元素從DOM移除家夺。當(dāng)父widget被銷毀時(shí)會(huì)自動(dòng)調(diào)用,如果它沒(méi)有父類 或需要將當(dāng)前widget移除但保留父級(jí)widget時(shí) 就必須顯示調(diào)用

與widget銷毀相關(guān)的函數(shù):

  • Widget.alive(deferred[, reject=false])
    由于RPC調(diào)用一般比較耗時(shí)伐弹,可能在它執(zhí)行完成的時(shí)候widget已經(jīng)被銷毀了拉馋,這時(shí)在會(huì)在一個(gè)無(wú)效的widget對(duì)象上做操作,alive可用于處理rpc調(diào)用惨好,并保證RPC調(diào)用返回后只在有效的widget上執(zhí)行對(duì)應(yīng)操作:
this.alive(this.model.query().all()).then(function (records) {
    // would break if executed after the widget is destroyed, wrapping
    // rpc in alive() prevents execution
    _.each(records, function (record) {
        self.$el.append(self.format(record));
    });
});

參數(shù):
deferred - deferred對(duì)象
reject - 默認(rèn)情況下如rpc調(diào)用完成后widget已被銷毀的話對(duì)應(yīng)的deferred對(duì)象只是被封鎖了煌茴,如果設(shè)置為True的話會(huì)將其調(diào)用拒絕

  • Widget.isDestroyed()
    如果widget已經(jīng)被銷銷毀了,會(huì)返回true日川,否則返回false

獲取DOM內(nèi)容

由于widget負(fù)責(zé)其DOM元素下的內(nèi)容蔓腐,可以用一個(gè)簡(jiǎn)便的方法去獲取它DOM元素內(nèi)的子片段:
Widget.$(selector) 將css選擇器應(yīng)用到widget的根DOM上

this.$(selector);
相當(dāng)于this.$el.find(selector);

重置DOM根元素

Widget.setElement(element)
將widget的根DOM設(shè)置為指定的DOM,參數(shù)element需為一個(gè)DOM元素或相應(yīng)的jquery對(duì)象

DOM事件處理

widget一般需要在相應(yīng)頁(yè)面內(nèi)響應(yīng)用戶的動(dòng)作龄句,這需要通過(guò)將事件綁定到DOM元素上來(lái)實(shí)現(xiàn)回论。

  • Widget.events
    事件是一個(gè)事件選擇器(事件名和css選擇器之間以空格分開)- 回調(diào)函數(shù)的映射,回調(diào)函數(shù)可以是widget內(nèi)置函數(shù)或一個(gè)函數(shù)對(duì)象分歇,this表示相應(yīng)widget
events: {
    'click p.oe_some_class a': 'some_method',
    'change input': function (e) {
        e.stopPropagation();
    }
},

回調(diào)函數(shù)只會(huì)被對(duì)應(yīng)根DOM的匹配子元素觸發(fā)傀蓉。如果事件選擇器留空的話,該事件是會(huì)被自動(dòng)綁定到widget的根DOM上职抡。

  • Widget.delegateEvents()
    該方法用于將事件綁定到DOM葬燎,當(dāng)設(shè)置好widget的根dom后會(huì)自動(dòng)被調(diào)用,可以通過(guò)重寫它來(lái)設(shè)置比events映射表指定的更為復(fù)雜的事件,但父級(jí)方法必須被顯式調(diào)用萨蚕,否則events不會(huì)被處理。

  • Widget.undelegateEvents()
    用于在dom被銷毀或重設(shè)時(shí)解綁events蹄胰,當(dāng)delegateEvents被覆蓋時(shí)岳遥,它也需要進(jìn)行覆蓋。

該方法需要與backbone的delegateEvents相兼容

Widget子類

可以通過(guò)extend來(lái)創(chuàng)建Widget()的子類裕寨,并提供了一些抽象方法和具體方法用于使用浩蓉。

var MyWidget = Widget.extend({
    // 渲染對(duì)象時(shí)使用的qweb模板
    template: "MyQWebTemplate",
    events: {
        // 事件綁定示例
        'click .my-button': 'handle_click',
    },

    init: function(parent) {
        this._super(parent);
        // 在渲染之前執(zhí)行的內(nèi)容
        // initialization
    },
    start: function() {
        var sup = this._super();
        // 渲染初始化邏輯

        // 允許多重deferred對(duì)象
        return $.when(
            // 從父類獲取異步信號(hào)
            sup,
            // 返回自己的異步信號(hào)
            this.rpc(/* … */))
    }
});


##使用
// 創(chuàng)建實(shí)例
var my_widget = new MyWidget(this);
// 渲染并插入到dom
my_widget.appendTo(".some-div");

##銷毀
my_widget.destroy();

開發(fā)規(guī)范

  • 避免使用id屬性,用id會(huì)讓部件重用變得很麻煩宾袜∧硌蓿可以使用class、dom節(jié)點(diǎn)或jquery來(lái)替代使用庆猫。如果一定要用的情況下认轨,需要使用_.uniqueId()來(lái)特別聲明:this.id = _.uniqueId('my-widget-')
  • 避免使用很通用的css名如content、navigation月培,以防止命名沖突嘁字。一般以根據(jù)它對(duì)應(yīng)的部分來(lái)命名。
  • 避免使用全局選擇器杉畜,因?yàn)槟硞€(gè)組件可能在同個(gè)頁(yè)面重復(fù)使用如儀表板纪蜒,像$(selector) or document.querySelectorAll(selector) 可能會(huì)導(dǎo)致錯(cuò)誤的操作,使用widget對(duì)應(yīng)的($el)$()來(lái)選擇
  • 不要認(rèn)為你的部件擁有或控制它自己的$el
  • html模板和渲染需要合用qweb
  • 所有用于顯示信息或處理事件的交互性質(zhì)的組件必須繼承自Widget() 并且使用它的api正確的實(shí)現(xiàn)

RPC

為了進(jìn)行顯示和交互此叠,需要使用rpc與odoo服務(wù)器通信纯续,odoo提供兩種api來(lái)處理:

  • 底層基于JSON rpc與模塊對(duì)應(yīng)python片段通信
  • 高級(jí)別的直接odoo模塊調(diào)用
    所有api都是異步調(diào)用的,所以它們都會(huì)返回deferred延期執(zhí)行對(duì)象

高級(jí)別API 直接調(diào)用odoo模塊

通過(guò)Model()來(lái)訪問(wèn)odoo的對(duì)象方法灭袁,通過(guò)call方法(來(lái)自web.Model)和 query方法(來(lái)自web.DataModel)來(lái)訪問(wèn)odoo服務(wù)器對(duì)象

  • call()是直接被映射到odoo服務(wù)端對(duì)象的同名方法的猬错,用法跟odoo模型的api使用只有以下三點(diǎn)區(qū)別:
  • 交互是異步的,所以在rpc中是返回的deferred延期對(duì)象(它們會(huì)自己處理對(duì)應(yīng)rpc調(diào)用結(jié)果)
  • 由于javascript規(guī)范沒(méi)有__getattr__method_missing特性茸歧,需要指定調(diào)度rpc的方法
  • 沒(méi)有池的概念兔魂,當(dāng)需要用的時(shí)候就實(shí)例化model代理,而不是從另一個(gè)(如全局)中獲取
var Users = new Model('res.users');

Users.call('change_password', ['oldpassword', 'newpassword'],
                  {context: some_context}).then(function (result) {
    // do something with change_password result
});
  • query()方法是搜索(odoo的search和read)的接口举娩,返回一個(gè)Query()對(duì)象析校,該對(duì)象不可改變但是可以基于它創(chuàng)建新的query對(duì)象,添加新的屬性和方法到原始對(duì)象铜涉。
Users.query(['name', 'login', 'user_email', 'signature'])
     .filter([['active', '=', true], ['company_id', '=', main_company]])
     .limit(15)
     .all().then(function (users) {
    // do work with users records
});

query在調(diào)用all()first()方法之前是不會(huì)實(shí)際執(zhí)行的智玻,這兩個(gè)方法每次調(diào)用都會(huì)觸發(fā)一個(gè)rpc請(qǐng)求≤酱可以用來(lái)進(jìn)行實(shí)時(shí)查詢吊奢。

class Model(name)

  • Model.name 對(duì)象所綁定的model名
  • Model.call(method[, args][, kwargs]) 使用對(duì)應(yīng)參數(shù)調(diào)用當(dāng)前模型的對(duì)應(yīng)方法

參數(shù):

  1. method (String) 通過(guò)rpc調(diào)用的模型方法
  2. args (Array<>) 位置匹配的參數(shù)列表
  3. kwargs (Object<>) 傳遞的關(guān)鍵字參數(shù)
  • Model.query(fields)

參數(shù):fields (Array<String>) 搜索時(shí)需要獲取的字段列表

class odoo.web.Query(fields)

第一部分方法是讀取方法,它們使用所調(diào)用對(duì)象的數(shù)據(jù)來(lái)響應(yīng)rpc請(qǐng)求
  • odoo.web.Query.all() - 讀取當(dāng)前Query對(duì)象所對(duì)應(yīng)的數(shù)據(jù),返回一個(gè)deferred的數(shù)組
  • odoo.web.Query.first() - 讀取當(dāng)前Query對(duì)象對(duì)應(yīng)的第一個(gè) 結(jié)果页滚,如果沒(méi)有結(jié)果返回null召边,有結(jié)果返回deferred對(duì)象
  • odoo.web.Query.count() - 獲取當(dāng)前Query對(duì)象可得到的記錄數(shù)量
  • odoo.web.Query.group_by(grouping...) - 獲取查詢數(shù)據(jù)的分組,

參數(shù): grouping (Array<String>) - 分組列表
返回: Deferred<Array<odoo.web.QueryGroup>> | null

第二部分方法是設(shè)置方法裹驰,它們會(huì)創(chuàng)建一個(gè)新Query對(duì)象并對(duì)相關(guān)屬性進(jìn)行擴(kuò)展或替換
  • odoo.web.Query.context(ctx) 添指定的環(huán)境變量添加到搜索中
  • odoo.web.Query.filter(domain) 將指定的domain表達(dá)式添加到查詢條件中隧熙,通過(guò)and與已存在的domain聯(lián)接
  • odoo.web.Query.offset(offset) 設(shè)置查詢的起始位置,會(huì)將原有的offset替換
  • odoo.web.Query.limit(limit) 設(shè)置查詢的數(shù)據(jù)量幻林,會(huì)將原來(lái)的limit替換
  • odoo.web.Query.order_by(fields…) 覆蓋原來(lái)的排序規(guī)則贞盯,像Django的QuerySet.order_by一樣
  • 接收多個(gè)排序字段,按重要性高到低排序沪饺,第一個(gè)優(yōu)先級(jí)最高躏敢,字段以字符串提供
  • 每個(gè)字段默認(rèn)是按升序,可以在字段前加-表示倒序
    與django不同整葡,它沒(méi)有用?來(lái)進(jìn)行隨機(jī)亂序和對(duì)關(guān)聯(lián)字段排序方法

**分組聚合 **
odoo有非常強(qiáng)大的分組運(yùn)算功能件余,但是它是遞歸的,并且第N+1層依賴于第n層所提供的數(shù)據(jù)遭居,所以當(dāng)odoo.models.Model.read_group()工作時(shí)這個(gè)api就不是那么直觀蛾扇。
odoo一般用Query()方法來(lái)代替 read_group()方法。

some_query.group_by(['field1', 'field2']).then(function (groups) {
    // do things with the fetched groups
});

該方法可以接受一個(gè)字段列表參數(shù)魏滚、也可以不帶參數(shù)執(zhí)行镀首,無(wú)參數(shù)時(shí)直接返回null而不是deferred對(duì)象
當(dāng)分組條件從其他地方來(lái)的時(shí)候,可以通過(guò)兩種方法來(lái)測(cè)試:

  • 對(duì)group_by所得到的結(jié)果進(jìn)行檢查:
var groups;
if (groups = some_query.group_by(gby)) {
    groups.then(function (gs) {
        // groups
    });
}
// no groups
  • 使用when()將返回值強(qiáng)制轉(zhuǎn)換為deferred對(duì)象
$.when(some_query.group_by(gby)).then(function (groups) {
    if (!groups) {
        // No grouping
    } else {
        // grouping, even if there are no groups (groups
        // itself could be an empty array)
    }
});

成功的情況下group_by返回的結(jié)果是一個(gè) QueryGroup()數(shù)組

class odoo.web.QueryGroup() 返回分組的屬性key鼠次,有以下幾種
  • grouped_on -- 基于哪個(gè)字段進(jìn)行分組計(jì)算
  • value -- 當(dāng)前分組的grouped_on的值
  • length -- 分組內(nèi)的記錄數(shù)量
  • aggregates -- 分組聚合結(jié)果的 {field: value} 映射
odoo.web.QueryGroup.query([fields...]) 相當(dāng)于Model.query() 更哄,但只包含當(dāng)前分組內(nèi)的記錄,返回一個(gè)Query對(duì)象供后續(xù)使用
odoo.web.QueryGroup.subgroups() 返回一個(gè)指向當(dāng)前的子QueryGroup()的數(shù)組的deferred對(duì)象

底層API:RPC調(diào)用python程序

Session()對(duì)象(通過(guò)web.Session實(shí)例化)的rpc方法提供了一個(gè)低級(jí)別api用來(lái)直接調(diào)用python程序腥寇,該方法接收一個(gè)完整URL成翩、一個(gè)參數(shù)key=>value映射表 作為參數(shù),并將對(duì)應(yīng)獲取的結(jié)果轉(zhuǎn)換成json格式

session.rpc('/web/dataset/resequence', {
    model: some_model,
    ids: array_of_ids,
    offset: 42
}).then(function (result) {
    // resequence didn't error out
}, function () {
    // an error occured during during call
});

web client

javascript模塊系統(tǒng)

從odoo v8開始使用一套跟requirejs類似的js模塊系統(tǒng)赦役,它有以下優(yōu)點(diǎn):

  • 依賴關(guān)系可以保證按順序加載
  • 更容易將文件分割成更小的邏輯單元
  • 沒(méi)有全局變量
  • 很容易檢查依賴關(guān)系麻敌,讓重構(gòu)變得容易很多

缺點(diǎn):

  • 如果要通過(guò)odoo交互就必須用模塊系統(tǒng)加載,因?yàn)橛泻芏鄬?duì)象只在模塊系統(tǒng)中能用
  • 不支持循環(huán)依賴

在這種模式下掂摔,通過(guò)require來(lái)導(dǎo)入需要的模塊术羔,并且顯示聲明所輸出的對(duì)象。

odoo.define('addon_name.service', function (require) {
    var utils = require('web.utils');
    var Model = require('web.Model');

    // do things with utils and Model
    var something_useful = 15;
    return  {
        something_useful: something_useful,
    };
});

上面的代碼創(chuàng)建了一個(gè)名叫addon_name.service的模塊乙漓,使用odoo.define函數(shù)定義级历。

odoo.define函數(shù)有兩個(gè)參數(shù):
1.name - 新定義的模塊名

2.function - 在里面定義該模塊實(shí)際包含的內(nèi)容,接收一個(gè)require參數(shù)叭披,如果需要輸出內(nèi)容就需要有對(duì)應(yīng)返回寥殖,require函數(shù)用于獲取依賴的模塊。

用javascript來(lái)導(dǎo)入需要的模塊就聲明輸出內(nèi)容,web客戶端會(huì)自動(dòng)進(jìn)行加載嚼贡。模塊在文件中定義熏纯,一般最好一個(gè)文件對(duì)應(yīng)一個(gè)模塊。模塊可以返回一個(gè)deferred對(duì)象粤策,這樣該模塊只在deferred執(zhí)行后才加載樟澜,而且模塊可以被廢棄,并在控制臺(tái)記錄對(duì)應(yīng)信息:

Missing dependencies - 該模塊不會(huì)出現(xiàn)在頁(yè)面中掐场,可能是javascript文件不在頁(yè)面中或模塊名有錯(cuò)誤

Failed modules - 有javascript錯(cuò)誤
Rejected modules - 模塊返回的是一個(gè)廢棄的deferred
Rejected linked modules - 該模塊依賴于已廢棄的模塊
Non loaded modules - 模塊所依賴的模塊不存在或有錯(cuò)誤

Web client結(jié)構(gòu)

  • framework/文件夾包含所有底層的模塊
  • web.ajax 用于處理rpc調(diào)用
  • web.core 核心模塊往扔,給出很多有用的對(duì)象如qweb,_t
  • web.Widget 包含widget類
  • web.Model 抽象化的web.ajax贩猎,用于直接調(diào)用服務(wù)端模型的方法
  • web.sessionodoo.session
  • web.utils 有用的代碼段
  • web.time 時(shí)間相關(guān)函數(shù)
  • views/文件夾包含所有視圖定義
  • widgets/包含獨(dú)立的部件
  • js/文件夾包含一些重要的文件
  • action_manager.js ActionManager 類
  • boot.js 模塊系統(tǒng)的入口
  • menu.js 頂級(jí)菜單的定義
  • web_client.js 部件WebClient
  • view_manager.js 包含ViewManager

還有其他兩個(gè)文件:tour.js用于tour熊户,compatibility.js用于將舊系統(tǒng)與新系統(tǒng)兼容,在這個(gè)文件中每個(gè)模塊名被輸出到全局變量odoo中吭服。理論上模塊可以不通過(guò)變量odoo使用嚷堡。

javascript習(xí)慣

  • 在模塊最前面聲明所有依賴關(guān)系,一般按模塊名字母順序來(lái)排列
  • 在最后聲明所有輸出
  • 在模塊開始時(shí)添加use strict 聲明
  • 以合適的名字命名模塊如:addon_name.description
  • 類名首字母大寫如:ActionManager 艇棕,但其他的小寫如web.ajax
  • 每個(gè)文件只定義一個(gè)模塊

odoo web client測(cè)試

詳見:http://www.odoo.com/documentation/10.0/reference/javascript.html#testing-in-odoo-web-client


譯自odoo官方文檔:http://www.odoo.com/documentation/10.0/reference/javascript.html 蝌戒,不當(dāng)之處歡迎批評(píng)指正。

內(nèi)容發(fā)布自http://www.reibang.com/u/6fdae8ec06bc沼琉,轉(zhuǎn)載請(qǐng)注明出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末北苟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子打瘪,更是在濱河造成了極大的恐慌友鼻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闺骚,死亡現(xiàn)場(chǎng)離奇詭異彩扔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)僻爽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門虫碉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人胸梆,你說(shuō)我怎么就攤上這事敦捧。” “怎么了碰镜?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵绞惦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我洋措,道長(zhǎng)济蝉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮王滤,結(jié)果婚禮上贺嫂,老公的妹妹穿的比我還像新娘。我一直安慰自己雁乡,他們只是感情好第喳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著踱稍,像睡著了一般曲饱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上珠月,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天扩淀,我揣著相機(jī)與錄音,去河邊找鬼啤挎。 笑死驻谆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庆聘。 我是一名探鬼主播胜臊,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伙判!你這毒婦竟也來(lái)了象对?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宴抚,失蹤者是張志新(化名)和其女友劉穎勒魔,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酱塔,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沥邻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了羊娃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唐全。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蕊玷,靈堂內(nèi)的尸體忽然破棺而出邮利,到底是詐尸還是另有隱情,我是刑警寧澤垃帅,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布延届,位于F島的核電站,受9級(jí)特大地震影響贸诚,放射性物質(zhì)發(fā)生泄漏方庭。R本人自食惡果不足惜厕吉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望械念。 院中可真熱鬧头朱,春花似錦、人聲如沸龄减。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)希停。三九已至烁巫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宠能,已是汗流浹背亚隙。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棍潘,地道東北人恃鞋。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓崖媚,卻偏偏與公主長(zhǎng)得像亦歉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畅哑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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