使用angularJS过滤PHP列表

I am trying to create a blog page and I chose WordPress over AngularJS so Google can index the page ( or at least that's what i think it works). So for now I have a list which looks like this

<ul>
    <li id="1">
        <h2>My first Post</h2>
        <p>The Message...</p>
    </li>
    <li id="2">
        <h2>My second Post</h2>
        <p>The Message...</p>
    </li>
    <li id="3">
        <h2>My third Post</h2>
        <p>The Message...</p>
    </li>
</ul>

but PHP is pretty static so I want to create a angular filter to filter posts by title, but I don't really know how to do this.

I was thinking to create a hide class for <li> items and somehow if a post should be deleted because of the filter, to add the hide class to it. I try to mix this angular so I can have a dynamic search instad loading the page again after searching.

You could create a directive to wrap the html content you receive from php, pass the filter term and which element of the list you want to check).

Here is a plunker: http://plnkr.co/edit/Bv2opi5CHfJa0pQyFrBc?p=preview

(this require jquery to hide and show, but you can use css({'display':'none|block'}) too)

(maybe you could modify the directive to apply the filter term to ignore the case of the words)

app.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
    $scope.model = {
        filter: ''
    };
});

app.directive('myHtmlFilter', [function() {
    return {
        restrict: 'A',
        scope: {
          filter: '=myHtmlFilter',
          element: '@'
        },
        link: function(scope, elem, attrs) {
          scope.$watch('filter', function(newval, oldval) {
            elem
              .find('ul>li')
                  .hide()
                  .find(scope.element)
                  .filter(':contains("'+scope.filter+'")')
               .parent()
                  .show();
          })
        }
    }
}]);

index.html

<input type="text" ng-model="model.filter" />

<div my-html-filter="model.filter" element="h2">
  <ul>
    <li id="1">
        <h2>My first Post</h2>
        <p>The Message...</p>
    </li>
    <li id="2">
        <h2>My second Post</h2>
        <p>The Message...</p>
    </li>
    <li id="3">
        <h2>My third Post</h2>
        <p>The Message...</p>
    </li>
  </ul>
</div>

Edit I updated the plunker with a more complete example than the code shown here.

If you can have the JSON approach, then Angular automatically does that for you.

Just go with a simple filter solution:

<input ng-model="criteria"/>

<ul>
  <li ng-repeat="entry in entries | filter:{title: criteria}" id="{{entry.id}}">
    <h2>{{entry.title}}</h2>
    <p>{{entry.body}}</p>
  </li>
</ul>

In your controller (or any JS with access to the container scope):

app.controller('MainCtrl', function($scope) {
  $scope.criteria = "Title";

  $scope.entries = [
    {
      id: 1,
      title: 'My title',
      body: 'contents...'
    },
    {
      id: 2,
      title: 'The other content',
      body: 'contents...'
    },
    {
      id: 3,
      title: 'Another title',
      body: 'contents...'
    },
    {
      id: 4,
      title: 'Something completely different',
      body: 'contents...'
    }
  ];
});

You can even use $http service to retrieve the JSON file:

app.controller('MainCtrl', function($scope) {
  $scope.criteria = "Title";
  $scope.entries = $http.get('path/to/entries.json');
});

Considering you don't have a service that will return only the JSON formatted items, the best approach would be creating a directive that remove the li, parse their contents to an object and use ng-repeat in a template. Something like this:

var app = angular.module('plunker', []);

app.directive('filtered', function() {
  return {
    scope: {
      criteria: '=filtered'
    },
    compile: function(elm, attr) {
      var entries = [];

      elm.find('li').each(function(index, item) {
        var entry;

        $item = angular.element(item);

        entries.push({
              id: $item.attr('id'),
          title: $item.find('h2').text(),
          body: $item.find('p').text()
        });
      }).remove();

      elm.append(
        '<li ng-repeat="entry in entries | filter:{title: criteria}" id={{entry.id}}>' +
          '<h2>{{entry.title}}</h2>' +
          '<p>{{entry.body}}</p>' +
        '</li>'
      );

      return function(scope) {
        scope.entries = entries;
      };
    }
  };
});

And in your HTML you just decorate the list with the directive:

<input ng-model="userCriteria">

<ul filtered="userCriteria">
  <li id="1">
    <h2>My first Post</h2>
    <p>The Message...</p>
  </li>
  <li id="2">
    <h2>My second Post</h2>
    <p>The Message 2...</p>
  </li>
  <li id="3">
    <h2>My third Post</h2>
    <p>The Message 3...</p>
  </li>
</ul>

I've put together a Plnkr here. Go ahead and change the HTML list and it will automatically include that items.