.メインメニュー

.検索

.ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録

.フォーラムメニュー

.オンライン状況
16 人のユーザが現在オンラインです。 (13 人のユーザが フォーラム を参照しています。)

登録ユーザ: 0
ゲスト: 16

もっと...

.
.リンク集

メイン
   helper,component,script
     cakephp と angularjs
投稿するにはまず登録を

このエントリーをはてなブックマークに追加
スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
custar
投稿日時: 2012-8-31 17:02
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
cakephp と angularjs
cakephp と angularjs を組み合わせて使ってみたらどうなるか試しています。

- cakephp v2.2.1
- angularjs v1.0.1

bake 後のソースをなるべく変更しないよう扱ってます。
paginator は現状無視してください。

Controll/BsController.php

<?php
public function index() {
    
$this->B->recursive 0;
    
$this->set('bs'$this->paginate());
    
$this->set('_serialize', array('bs'));
}
?>



View/Bs/index.ctp

<?php
<div class="bs index">
  <
h2><?php echo __('Bs'); ?></h2>

  <table class="table table-striped">
    <thead>
      <tr>
        <th><?php echo $this->Paginator->sort('id'); ?></th>
        <th><?php echo $this->Paginator->sort('name'); ?></th>
        <th class="actions"><?php echo __('Actions'); ?></th>
      </tr>
    </thead>
    <tbody ng-controller="BsCtrl">
      <tr ng-repeat="b in bs">
        <td>{{b.B.id}}</td>
        <td>{{b.B.name}}</td>
        <td class="actions">
          <?php echo $this->NgHtml->link(__('View'), array('action' => 'view''{{b.B.id}}')); ?>
          <?php echo $this->NgHtml->link(__('Edit'), array('action' => 'edit''{{b.B.id}}')); ?>
          <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete''{{b.B.id}}'), ...); ?>
        </td>
      </tr>
    </tbody>
  </table>
</div>
?>



<a> では href を使うなということなので、
<a> 出力を angular 用に書き換えるため、
NgHtmlHelper というのを用意して (下記↓)、内容を強引に書き換えています。


View/Helper/NgHtmlHelper.php

<?php
App
::uses('HtmlHelper''View/Helper');

class 
NgHtmlHelper extends HtmlHelper {
    
    public function 
link($title$url null$options = array(), $confirmMessage false) {
        
$output parent::link($title$url$options$confirmMessage);
        
$replacements = array(
            
'/href/' => 'ng-href',
            
'/%7B/i' => '{',
            
'/%7D/i' => '}',
        );
        return 
preg_replace(array_keys($replacements), array_values($replacements), $output);
    }
}
?>


HtmlHelper の link() のままだと、
curly-brace が link() 内の rawurlencode() により escape されてしまい、
angular が認識できなくなります。

で、上記の通り置換して元に戻しています ('%7B' => '{', '%7D' => '}')。

href の置換は余計かもしれませんが、
敢えて HtmlHelper の link() の引数と変えるのが面倒なので、置換で済ませました。

何かもっと楽な方法があったら提示してください。


また、HtmlHelper と同様に FormHelper も angular 用の出力を行えるよう変更したのですが、
「TypeError: document.post_504068919b862.submit is not a function」というエラーを出して失敗します。

これは、テンプレートとして使われた <form> の name が、各エントリーに対して変更されていないのが理由です。

delete に関しては、どう実装するかに依るので、保留します。


webroot/js/controllers.js

<?php
function BsCtrl($scope$http) {
    
$http.get('/tests/angular/bs.json').success(function(data) {
        
$scope.bs data.bs;
    });
}
?>




まだ途中ですが、他の方で、自分はこう実装してみた、というのがあったらアドバイスしてください。

次は、view, edit ですね。
custar
投稿日時: 2012-8-31 20:37
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
add を試しています。


View/Bs/add.ctp

<?php
<div class="bs form">
  <?
php echo $this->Form->create('B', array('default' => false'ng-submit' => 'submit(data)')); ?>
    <fieldset>
      <?php echo $this->Form->input('name', array('ng-model' => 'data.B.name')); ?>
    </fieldset>
  <?php echo $this->Form->end(__('Submit')); ?>
</div>
?>




webroot/js/controllers.js

<?php
function BsCtrl($scope$http) {
    
$scope.submit = function(data) {
        var 
postData = { "_method" "POST" }
        , 
key;
        
angular.forEach(data, function(valuesalias) {
            
angular.forEach(values, function(valuefieldName) {
                
key 'data['alias +']['fieldName +']';
                
postData[key] = value; ........................................... (1)
            });
        });
        
        
$http.post('/tests/angular/bs/add.json', $.param(postData), { ............ (2)
            
headers: {
                
'Content-Type''application/x-www-form-urlencoded'
            
}
        })
        .
success(function(datastatusheadersconfig) {
            
////
        
})
        .
error(function(datastatusheadersconfig) {
            
////
        
});
    };
}
?>



postData をわざわざ作っているところ (1) と、
jQuery.param() で serialize しているところ (2) が嫌ですね。
# serialize しないと json で送られてしまいます

angular だけで何とかならないかなぁ。
jQuery 使わざるを得ないのかな?

どなたかいい方法知りませんか?

# まだ angularjs の Developer Guide を読んでないから詳しく分からない。
custar
投稿日時: 2012-9-1 10:46
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
View/Bs/add.ctp

<?php
<?php echo $this->Form->create('B', array('default' => false)); ?>
  <fieldset>
    <?php
      
echo $this->Form->input('name', array('ng-model' => 'data.B.name'));
    
?>
  </fieldset>
<?php echo $this->Form->end(array('label' => __('Submit'), 'ng-click' => 'submit($event, data)')); ?>
?>


ng-submit を止め、
ng-click にして $event を捉え、

webroot/js/controllers.js

<?php
$scope
.submit = function(evtdata) {
    var 
postData = $(evt.target).closest('form').serialize()
        
    
$http.post('/tests/angular/bs/add.json'postData, {
        
headers: {
            
'Content-Type''application/x-www-form-urlencoded'
        
}
    })
?>


jquery の serialize() を使うことで略す。


twitter bootstrap の modal を使って新規作成しているのだが、
新規作成したエントリー (b) を server から受け取れば、
以下のようにして、画面のリフレッシュなしに index.ctp に b が追加されることを確認した。
便利ね。


<?php
$scope
.bs.push(data.result.b);
?>




また、新規作成が成功した場合は、上記 modal を自動的に閉じたいのだが、
controller から view を扱うのは宜しくないのだろうが、
簡単には以下で出来る。


<?php
$('.modal:visible').modal('hide');
or
$(
evt.target).closest('.modal').modal('hide');
?>



angular の手続きでやりたければ、もしかしたら以下が参考になるかもしれない。

- Show a Twitter Bootstrap Modal with Angular.js Directives
- AngularUI / Modal
- Bootstrap modal popup directives with Angular
- Twitter bootstrap modal dialog widget


他にアイデアがあれば、提示して下さい。
custar
投稿日時: 2012-9-2 14:24
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
以下を参考にして cakephp を RESTful にして....で?
どうすればいいのやら。

分かる人がいたら教えてください。


- Wire up a Backend
http://angularjs.org/

- $resource
http://docs.angularjs.org/api/ngResource.$resource
yasu00000
投稿日時: 2012-9-2 14:58
Baker スタート
登録日: 2008-11-3
居住地:
投稿: 13
Re: cakephp と angularjs
Angularjsはまだ触ったことがないので、cakephpとangularjsの定期ポスト楽しみにしてます!

Angularjsではありませんが、CakePHPとBackbone.jsについてはブログに書かれている方が居らっしゃいます。

http://cx5software.com/blog/2012/03/26/cakephp-backbone-js/

cakephpをRESTfulにして...の部分は参考になるかもしれません。
custar
投稿日時: 2012-9-2 16:50
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
引用:

yasu00000さんは書きました:
cakephpをRESTfulにして...の部分は参考になるかもしれません。


server 側を RESTful にするのは問題ないと思っています。
不明なことが多いのは client 側で。

angular でどう記述すれば良いのやら。

まだ、ブログを読んでいませんが。


p.s.
---
ブログを読んでみましたが、
残念ながら、server 側の参考にはなりますが、
やはり client 側 (angular) の参考にはなりませんでした。
でも、情報を提供する姿勢は感謝します。
custar
投稿日時: 2012-9-7 19:42
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
暫く angular にまわす余力がないので、
他の方で扱える方が居らっしゃったら、追加してください。

別 thread でも構いませんが。
custar
投稿日時: 2012-9-17 19:03
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
# currency filter に関して...
# angular を触り始めてますが、cake に直接関係ないです。

angular の currency filter では¥記号が付けられるだけで、
小数点以下を消す手段が無さそうだったので、
ソースを眺めてみました。

angular.js v1.0.2

<?php
function currencyFilter($locale) {
    var 
formats $locale.NUMBER_FORMATS;
    return function(
amountcurrencySymbol){
        ...
        return 
formatNumber(amount, ..., formats.DECIMAL_SEP2).
            
replace(/u00A4/gcurrencySymbol);
    };
}
?>



formatNumber() の最後の引数 (fractionSize) に "2" がベタに書かれてます。
現状変更できませんね。


では、強引に末尾を消します。

yen_controller.js

<?php
angular
.module('myApp', []).filter('yen', function($filter) {
    return function(
input) {
        return 
$filter('currency')(input'\u00A5').replace(/.00$/, '');
    };
});
?>




index.html

<!doctype html>
<html ng-app="myApp">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
    <script src="yen_controller.js"></script>
  </head>
  <body>
    <div ng-init="amount = 10000">
      <h1>{{amount | currency:"\"}}</h1>
      <h1>{{amount | yen}}</h1>
    </div>
  </body>
</html>


結果:
\10,000.00
\10,000
custar
投稿日時: 2012-9-18 0:51
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
validation error を表示させるため、下記 (1) の $error を設定するが、
cake の場合、<input> の name は data[B][name] のような書式になる。
敢えてこのまま使うなら、javascript object として考えて、name を double quotation で囲んであげれば動いた。

但し、angular を使う場合でも、
cake の書式を使い続ける必要があるのか現時点では不明。


<?php
<div class="bs form">
    <?
php echo $this->Form->create('B', array('name' => 'createB''novalidate')); ?>
        <fieldset>
            <?php
                $errorRequired 
$this->Html->tag('span'__('Required'), array(
                    
'ng-show' => 'createB["data[B][name]"].$error.required' ......... (1)
                ));
                echo 
$this->Form->input('name', array(
                    
'ng-model' => 'b.B.name'
                    
'required',
                    
'after' => $errorRequired,
                ));
            
?>
        </fieldset>
    <?php echo $this->Form->end(__('Submit')); ?>
</div>
?>




出力結果:

<?php
<div class="input text required">
    <
label for="BName">Name</label>
    <
input type="text" id="BName" maxlength="5" required="" ng-model="b.B.name" name="data[B][name]">
    <
span ng-show="createB["data[B][name]"].$error.required">Required</span>
</
div>
?>


custar
投稿日時: 2012-9-18 17:17
Cake 職人
登録日: 2007-5-31
居住地:
投稿: 260
Re: cakephp と angularjs
# またまた cake に結び付かないけど...

truncate filter を使ってみました。

参考:
- Truncate Filter Example
http://jsfiddle.net/tUyyx/


index.html

<?php
<!doctype html>
<
html ng-app="myApp">
  <
head>
    <
script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
    <script src="filters.js"></script>
  </head>
  <body>
    <div>
      <label>Words:</label>
      <input type="text" ng-model="words" ng-init="words = 'abcdefghijklmnopqrstu'"><br/>
      <label>Amount:</label>
      <input type="text" ng-model="amount" ng-init="amount = 100000"><br/>
      <hr>
      <h1>{{words | truncate:5}}</h1>
      <h1>{{amount | yen}}</h1>
    </div>
  </body>
</html>
?>



filters.js

<?php
angular
.module('myApp', ['filters']);

angular.module('filters', [])
/**
 * Yen Filter
 * @return string
 */
.filter('yen', function($filter) {
   return function(
input) {
      return 
$filter('currency')(input'\u00A5').replace(/.00$/, '');
   };
})
/**
 * Truncate Filter
 * @Param string
 * @Param int, default = 10
 * @Param string, default = "..."
 * @return string
 */
.filter('truncate', function () {
   return function (
textlengthend) {
      if (!
angular.isString(text))
         return 
'';
     
      if (
isNaN(length))
         
length 10;

      if (
end === undefined)
         
end "...";

      if (
text.length <= length || text.length end.length <= length) {
         return 
text;
      }
      else {
         return 
String(text).substring(0length-end.length) + end;
      }
   };
});
?>



結果:
ab...
\100,000
(1) 2 3 4 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 


. .