Laravel Blade模板在尝试获取非对象属性时如何返回null而不是ErrorException

时间:2016-12-15 15:50:43

标签: php laravel laravel-5 laravel-blade

我正在编写一些Laravel Blade模板,我的模型可能包含空对象。我非常想尝试获取object属性,如果有错误,只需返回null。

所以不必写这个:

package lca;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.JComboBox;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

public class combo extends JFrame {
Connection connection = null;
PreparedStatement prepared = null;
ResultSet rs = null;
 JComboBox<String> comboBox,comboBox_1,comboBox_2;

 String sel1 , sel2;

 public combo() {
    getContentPane().setLayout(null);

     comboBox = new JComboBox<String>();


    comboBox.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            sel1 = (String) comboBox.getSelectedItem();
            popcombo1();
            comboBox_1.setSelectedIndex(-1);
        }
    });
    comboBox.setBounds(41, 77, 146, 20);
    getContentPane().add(comboBox);

    comboBox_1 = new JComboBox<String>();
    comboBox_1.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            sel2 = (String) comboBox_1.getSelectedItem();
            popcombo2();
        }
    });
    comboBox_1.setBounds(41, 108, 146, 20);
    getContentPane().add(comboBox_1);

    comboBox_2 = new JComboBox<String>();
    comboBox_2.setBounds(41, 139, 146, 20);
    getContentPane().add(comboBox_2);

    JButton btnLoad = new JButton("Load");
    btnLoad.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            try {
                String sql1 = "SELECT DISTINCT Name FROM Project_info  " ;
                Class.forName("org.sqlite.JDBC");
                 Connection connection2 =        DriverManager.getConnection("jdbc:sqlite:C:\\Users\\Nitesh\\Desktop\\SM\\Project.sqlite");


                prepared = connection2.prepareStatement(sql1);
                rs = prepared.executeQuery();
                while(rs.next())
                {
                    String name  = rs.getString("Name");
                     comboBox.addItem(name);
                }
                connection2.close();}
                catch(Exception e3)
                {
                    System.err.println( e3.getClass().getName() + ": " + e3.getMessage() );
                }

            finally {
                try{
                rs.close(); prepared.close();
                //connection2.close(); 
                }
                catch(Exception e1) { } }
            comboBox.setSelectedIndex(-1); 
            }



    });
    btnLoad.setBounds(41, 11, 89, 23);
    getContentPane().add(btnLoad);
}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Throwable e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                combo frame = new combo();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

  }
    public void popcombo1() {
    comboBox_1.removeAllItems();
     try {
        String sql1 = "SELECT DISTINCT Pro_cat FROM Project_info where Name  = '" +sel1 +  "'" ;
        Class.forName("org.sqlite.JDBC");
         Connection connection2 = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\Nitesh\\Desktop\\SM\\Project.sqlite");


        prepared = connection2.prepareStatement(sql1);
        rs = prepared.executeQuery();
        while(rs.next())
        {
            String name  = rs.getString("Pro_cat");
             comboBox_1.addItem(name);
        }
        connection2.close();}
        catch(Exception e3)
        {
            System.err.println( e3.getClass().getName() + ": " + e3.getMessage() );
        }

    finally {
        try{
        rs.close(); prepared.close();
        //connection2.close(); 
        }
        catch(Exception e1) { } }
    comboBox_1.setSelectedIndex(-1);
    }
  public void popcombo2() {
    comboBox_2.removeAllItems();
    try {
        String sql1 = "SELECT DISTINCT Sub_cat FROM Project_info where Pro_cat = '" +sel2 +  "' AND Name = '"+ sel1+ "'" ;
        Class.forName("org.sqlite.JDBC");
         Connection connection2 = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\Nitesh\\Desktop\\SM\\Project.sqlite");


        prepared = connection2.prepareStatement(sql1);
        rs = prepared.executeQuery();
        while(rs.next())
        {
            String name  = rs.getString("Sub_cat");
             comboBox_2.addItem(name);
        }
        connection2.close();}
        catch(Exception e3)
        {
            System.err.println( e3.getClass().getName() + ": " + e3.getMessage() );
        }

    finally {
        try{
        rs.close(); prepared.close();
        //connection2.close(); 
        }
        catch(Exception e1) { } }

    }


}

我可以这样写:

arr=arr.toArray();
//.... modify arr
//....
arr= arr.fromJS(arr);

如果子对象为null,则结果计算为null。

我想只使用我的刀片模板执行此操作,而不是应用程序中的任何位置(我仍然希望在控制器中获取错误)。

有没有简单的方法来实现这一目标?我也真的不想每次都在刀片模板中尝试/捕获异常。

基本上,当我不关心I child是null时,我正在尝试使刀片模板更容易/更短,如果它为null,那么它的不存在属性对于渲染部分也应该为null

3 个答案:

答案 0 :(得分:4)

您可以将array_get用作:

{{ array_get($model, 'child_object_that_may_be_null.interesting_property') }}
  

array_get函数使用“点”表示法从深层嵌套数组中检索值。

注意 - 它可能只适用于Laravel的模型对象

答案 1 :(得分:1)

您可以在对象中检查可为空的值,并将它们初始化为stdClass。

$properties = get_object_vars($model);
foreach ($properties as $k => $v) {
    if ($v === null) $model->$k = new stdClass;
}

答案 2 :(得分:1)

我一直被这种情况所困扰。当我知道他们会有这种数据显示时,我开始在我的对象上添加displayAttribute个访问者。特别适用于日期或多层次的关系。

因此,如果我有一个与合同相关的服务模型,并且该合约有start_date我要展示,我会向我添加getDisplayContractStartDateAttribute服务模式并在那里检查。这样,如果没有合同,我也可以选择显示一条消息。像这样:

public function getDisplayContractStartDateAttribute(){
    if ($this->contract && $this->contract->starts_at){
        return $this->contract->starts_at->format('m/d/Y @ g:i a');
    } else {
        return 'Start date or contract missing';
    }
}

所以现在我的Blade模板中的任何地方都可以访问$service->displayContractStartDate,而不必担心会发生这种可怕的错误。

如果您担心使用这些与数据库无关的方法过度扩展模型,请考虑使用特征来包含给定模型的所有displayAttribute方法。

或者,如果您担心关注点分离,可以使用装饰器并像$service->decorator->contractStartDate()那样访问它,但我个人认为这太复杂了。