Giới thiệu CWidget

Một phần của tài liệu Yiiframewo (Trang 50 - 53)

Chúng tôi sẽ sử dụng một widget Yii để xây dựng một ý kiến gần đây của portlet và hiển thị nó trên trang chính của dự án chi tiết để chúng ta có thể thấy hoạt động của bình luận trên tất cả các vấn đề liên quan đến dự án. Để chứng minh sự dễ dàng tái sử dụng, chúng tôi sẽ mang nó một bước xa hơn và cũng có thể hiển thị một danh sách các dự án cụ thể ý kiến về trang chi tiết dự án.

Tạo hàm :Tìm comment gần đây: Trong Comment::findRecentComment. public static function findRecentComments($limit=10, $projectId=null) { if($projectId != null) { return self::model()->with(array( 'issue'=>array('condition'=>'project_id='.$projectId)))->findAll(array( 'order'=>'t.create_time DESC', 'limit'=>$limit, )); } else {

//get all comments across all projects

return self::model()->with('issue')->findAll(array( 'order'=>'t.create_time DESC', 'limit'=>$limit, )); } }

Method trê n có 2 tham số $limit để hạn chế số lượng, $projectId xác định id dự án mà các comment nằm trong đó. Tham số thứ 2 sẽ giúp cho widget sử dụng hiển thị tất cả comment trong 1 dự án.Vì vậy, nếu id đầu vào dự án đã được chỉ định, nó hạn chế các kết quả trả về chỉ những ý kiến liên kết với dự án, nếu không, tất cả các ý kiến trên tất cả các các dự án được trả lại.

Thêm chi tiết về các truy vấn AR quan hệ trong Yii

Hai truy vấn trên quan hệ AR một chút mới cho chúng tôi. Chúng tôi đã không được sử dụng rất nhiều các tùy chọn này trong các truy vấn trước đó của chúng tôi. Trước đây, chúng tôi đã được sử dụng phương pháp đơn giản nhất để thực hiện các truy vấn quan hệ:

1. Tải instance AR.

2. Truy cập thuộc tính quan hệ được định nghĩa trong method relation ().

Ví dụ, nếu chúng ta muốn truy vấn cho tất cả các sản phẩm (Issue) liên quan tới dự án(Project) có id # 1, chúng tôi sẽ thực hiện hai dòng mã sau đây:

// retrieve the project whose ID is 1 $project=Project::model()->findByPk(1);

// retrieve the project's issues: a relational query is actually being performed behind the scenes here $issues=$project->issues;

Đây là một phương thức hơi chậm tại vì nó còn chờ có mã id hợp lệ mới thực hiện.Nếu như có quá nhiều dự án cần tải tương ứng với quá nhiều id cần nạp điều này sẽ gây ra việc chậm trễ. Vì thế chúng ta cần phải dùng giải pháp tốt hơn.

Eager Loading là một giải pháp truy xuất vào quan hệ của AR cài đặt cùng một time như trong trường hợp AR chính được yêu cầu. Điều này được dùng với with() method kết hợp cả find() hoặc findAll() method cho AR query. Ta thực hiện như sau :

$projects = Project::model()->with('issues')->findAll(); Trong Comment::findRecentComments() ta có :

return self::model()->with('issue')->findAll(array('order'=>'t.create_time DESC','limit'=>$limit,));

chúng ta chỉ định t.create_time cho biết ta muốn sử dụng cột của bảng chính. Nếu chúng ta muốn thay vì để các cột create_time issue , chúng tôi sẽ thay đổi, truy vấn thứ hai ví dụ, như sau:

return Comment::model()->with('issue')->findAll(array( 'order'=>'issue.create_time DESC',

'limit'=>$limit, ));

Để hoàn thành những gì ta đang thực hiện ta mở IssueController::loadModel() method :

public function loadModel($withComments=false) { if($this->_model===null) { if(isset($_GET['id'])) { if($withComments) { $this->_model=Issue::model()->with(array( 'comments'=>array('with'=>'author'))) ->findbyPk($_GET['id']); } else { $this->_model=Issue::model()->findbyPk($_GET['id']); } } if($this->_model===null)

throw new CHttpException(404,'The requested page does not exist.'); }

return $this->_model; }

Thay đổi IssueController::actionView(), as such: public function actionView()

{

$issue=$this->loadModel(true)

Thực hiện tạo Widget

Bây giờ chúng ta đã sẵn sàng để tạo ra các widget mới của chúng tôi sử dụng phương pháp mới của chúng tôi để hiển thị comment recent của chúng tôi.

Như chúng ta đã đề cập một widget trong Yii là một class extend từ CWidget framework . Chúng ta sẽ thêm widget mới của chúng tôi để được protected / component / , như các nội dung của thư mục này đã được quy định trong các file cấu hình chính để tự động tải về ứng dụng. Bằng cách này, chúng tôi sẽ không phải nhập khẩu một cách rõ ràng lớp mỗi lần chúng tôi muốn sử dụng nó. Chúng ta sẽ đặt tên RecentComments widget của chúng tôi, vì vậy chúng tôi cần thêm một tập tin php cùng tên thư mục. Thêm định nghĩa class RecentComment.php đến tập tin mới được tạo ra như sau:

protected / component / RecentComments.php

<?php /**

* RecentComments is a Yii widget used to display a list of recent comments */

class RecentComments extends CWidget {

private $_comments; public $displayLimit = 5; public $projectId = null; public function init() {

$this->_comments = Comment::model() ->findRecentComments($this->displayLimit, $this->projectId); }

public function getRecentComments() {

return $this->_comments; }

public function run() {

// this method is called by CController::endWidget() $this->render('recentComments');

}} }

Công việc chính khi tạo ra một widget mới là để ghi đè lên init () và run () lớp cơ sở. (method ) init khởi tạo các widget và được gọi là thuộc tính của nó đã được khởi tạo. Phương thức run () thực hiện các widget. Trong trường hợp này, chúng tôi chỉ cần khởi tạo các widget bằng cách yêu cầu ý kiến gần đây dựa trên $ displayLimit và projectId thuộc tính. Thực hiện của widget chỉ đơn giản là làm cho tập tin xem có liên quan đến viewfile , mà chúng ta vẫn chưa tạo ra. các tập tin xem, theo quy ước, được đặt trong view / directly trong cùng một thư mục widget cư trú, và có tên tương tự như widget, nhưng bắt đầu với một lá thư chữ thường. Tạo tập tin trong protecd/component / views /

recentComments.php. <ul>

<?php foreach($this->getRecentComments() as $comment): ?> <div class="author">

<?php echo $comment->author->username; ?> added a comment. </div>

<div class="issue">

<?php echo CHtml::link(CHtml::encode($comment->issue->name), array('issue/view', 'id'=>$comment- >issue->id)); ?>

</div>

<?php endforeach; ?> </ul>

Mở protected/views/project/index.php. Thêm vào cuối trang <?php $this->widget('RecentComments'); ?>

Giới thiệu Cportlet:

CPortlet là một phần của zii, mở rộng lớp thư viện chính thức đóng gói đi kèm với Yii. Nó cung cấp một lớp cơ sở tốt đẹp cho tất cả các vật dụng theo phong cách portlet. Nó sẽ cho phép chúng ta làm cho một tiêu đề tốt đẹp cũng như phù hợp HTML đánh dấu, vì vậy tất cả các portlet trên các ứng dụng có thể dễ dàng theo kiểu một cách tương tự. Một khi chúng ta có một tiện ích làm cho nội dung (như phụ tùng RecentComments của chúng tôi), chúng tôi chỉ đơn giản là có thể sử dụng nội dung trả lại

của các phụ tùng của chúng tôi như nội dung cho CPortlet, mà bản thân nó là một tiện ích, như nó cũng mở rộng từ CWidget. Chúng ta có thể làm điều này bằng cách đặt cuộc gọi của chúng tôi để các widget RecentComments giữa một beginWidget () và một endWiget () gọi cho CPortlet, như vậy:Thay thế vào protected/project/index <?php $this->beginWidget('zii.widgets.CPortlet', array( 'title'=>'Recent Comments', )); $this->widget('RecentComments'); $this->endWidget(); ?>

Thêm widget vào trang khác :

Add the following to the bottom of the protected/views/project/view.php file: <?php $this->beginWidget('zii.widgets.CPortlet', array(

'title'=>'Recent Project Comments', ));

$this->widget('RecentComments', array('projectId'=>$model->id)); $this->endWidget(); ?>

Một phần của tài liệu Yiiframewo (Trang 50 - 53)

Tải bản đầy đủ (PDF)

(64 trang)